質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

  • JavaScript

    17584questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    7122questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • Monaca

    1011questions

    「Monaca」はiOS、Android、Windows向けのアプリ開発に対応した、Cordovaベースのモバイルアプリ開発プラットフォームです。HTML5、JavaScriptといったWeb標準技術を用いてモバイルアプリ開発を行うことができます。

  • Cordova

    441questions

    Cordovaは様々なデバイスで使うことができるオープンソースなモバイル用開発プラットフォームです。開発者に各デバイスの元のプラットフォームで開発する必要をなくし、HTML・JavaScript・CSSなどの一般的なウェブのテクノロジーを使ってすべてのデバイスで展開することができるモバイルのアプリケーションを生成することを可能にします。

繰り返し処理の最後に関数を実行させたい

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 1,290

agepan

score 54

Monacaを利用してiPhoneで画像を取り込むJavaScriptコードを書いています。
現在のところ以下のようなコードになっていまして、画像の取り込みに成功しております。

画像の取り込みが完了したら次の関数(nextStep())を1回実行させたいと思い、下記コード内の現在コメントアウトにしている部分に記述したのですが、この場合ですと画像を10枚取り込むと10回実行されてしまいます。

画像を10枚取り込む操作をしたとき、最後の10枚目の処理後にnextStep()を1回だけ実行させるようなコードにしたいのですが、どのようにコードを修正すると実現するでしょうか?

よろしくお願いいたします。

// 画像を取得する

function getImage() {
  try{
    window.imagePicker.getPictures(
      function(results) {
        var content = '';
        for (var i = 0; i < results.length; i++) {
            camera_success(results[i]); // カメラ起動成功時camera_successを実行
        }
      }, function (error) {
          alert('Error: ' + error);
    }, {
      title: '画像を選択',
      width: 1000,
      height: 1000,
    }
  );
  } catch(e){
      alert(e);
  }
}



// カメラ起動時

function camera_success(results) {
  window.resolveLocalFileSystemURL( results, resolve_success, file_error );
}

function resolve_success(entry) {

  var fileExtension = entry.name;
  fileExtension = fileExtension.split('.');
  fileExtension = fileExtension[fileExtension.length-1].toLowerCase();

  var randomNumber = Math.floor( Math.random() * 99999 ); // 99999までのランダムな整数(乱数)を生成
  randomNumber = ( '00000' + randomNumber ).slice( -5 );

  var d = new Date();
  var n = d.getTime();
  var newFileName = 'image_' + n + '_' + randomNumber + '.' + fileExtension;
  var myFolderApp = 'myFolder';


  window.requestFileSystem( LocalFileSystem.PERSISTENT, 0, function( fileSys ) {
    fileSys.root.getDirectory( myFolderApp,
     {create: true, exclusive: false},
     function( directory ) {
      entry.copyTo( directory, newFileName,

        function move_success(entry) {

          var result = '<img src="' + myFolderApp + '/' + newFileName + '">'; // IMGタグを作成
          $(result).prependTo('.preview'); // HTMLに挿入


          // ★★★ ここに次に実行させる関数nextStep()を書くと、10枚取り込んだとき10回実行されてしまう ★★★


      } ,

       file_error );
   },
   file_error );
   },
  file_error );
}
function file_error(error) {
 alert('File System Error:' + error.code);
}

function camera_error(message) {
 alert('Camera Error:' + message);
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+3

本来はkei344さんやyambejpさんが提示されているPromiseなどを使った処理を行うべきです。
が、とりあえず期待する動作をさせたい、というのであれば以下のように処理する画像の件数を取得し、画像の数と処理件数が一緒になったら、希望の処理をするとかいう乱暴なやり方はあります。

// 追加
var imageLength = 0;
var length;

// 画像を取得する
function getImage() {
  try{
    window.imagePicker.getPictures(
      function(results) {
        var content = '';

        // 追加
        var imageLength = results.length;
        var length = 0;

        for (var i = 0; i < results.length; i++) {
          camera_success(results[i]); // カメラ起動成功時camera_successを実行
        }
      }, function (error) {
        alert('Error: ' + error);
      }, {
        title: '画像を選択',
        width: 1000,
        height: 1000,
      }
    );
  } catch(e){
    alert(e);
  }
}



// カメラ起動時

function camera_success(results) {
  window.resolveLocalFileSystemURL( results, resolve_success, file_error );
}

function resolve_success(entry) {

  var fileExtension = entry.name;
  fileExtension = fileExtension.split('.');
  fileExtension = fileExtension[fileExtension.length-1].toLowerCase();

  var randomNumber = Math.floor( Math.random() * 99999 ); // 99999までのランダムな整数(乱数)を生成
  randomNumber = ( '00000' + randomNumber ).slice( -5 );

  var d = new Date();
  var n = d.getTime();
  var newFileName = 'image_' + n + '_' + randomNumber + '.' + fileExtension;
  var myFolderApp = 'myFolder';


  window.requestFileSystem( LocalFileSystem.PERSISTENT, 0, function( fileSys ) {
    fileSys.root.getDirectory( myFolderApp,
                              {create: true, exclusive: false},
                              function( directory ) {
      entry.copyTo( directory, newFileName,

                   function move_success(entry) {

        var result = '<img src="' + myFolderApp + '/' + newFileName + '">'; // IMGタグを作成
        $(result).prependTo('.preview'); // HTMLに挿入

        // 追加
        length += 1;
        if (imageLength === length) {
          // ★★★ ここに次に実行させる関数nextStep()を書くと、10枚取り込んだとき10回実行されてしまう ★★★
        }
      } ,

                   file_error );
    },
                              file_error );
  },
                           file_error );
}

function file_error(error) {
  alert('File System Error:' + error.code);
}

function camera_error(message) {
  alert('Camera Error:' + message);
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/19 21:03

    ご回答ありがとうございました!
    こちらのコードを参考にしまして、取得画像総数をsessionStorageに保存し、for文とif文を使って画像総数と一致したとき=10枚取得したときに10枚目が処理されたときに関数を実行するコードを書きまして、きちんと動作しております。コード的にはスマートではないかもしれませんが、目的は達成することができました。
    ありがとうございました!

    キャンセル

+3

グローバル変数に回数を記録して分岐するか、Promiseを使うかどちらかだと思います。

【Promise - JavaScript | MDN】
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise

【JavaScript Promiseの本】
http://azu.github.io/promises-book/

【今更だけどPromise入門 - Qiita】
http://qiita.com/koki_cheese/items/c559da338a3d307c9d88

【Promiseについて0から勉強してみた - Qiita】
http://qiita.com/toshihirock/items/e49b66f8685a8510bd76

【AngularJS で Promise (defer)を使ってファイルシステムからファイルを読み込む (cordova filesystem) - Qiita】
http://qiita.com/mm36/items/a9869a2066ace1aed0a8

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/19 21:12

    ご回答ありがとうございます!
    Promiseという方法は初めて知りました。ただ自分のJavaScript技量が追いついていなく…きちんと理解するには時間が掛かりそうなので、取り急ぎsessionStorageとfor文、if文を用いて取得画像数と処理数が一致したとき(最終の画像を処理したとき)関数を実行するコードを書きまして、動いております。ただコード的にはPromiseなどを用いる方が正しいとのことですので、これからじっくりと学びたいと思います。ご回答頂き誠にありがとうございました!

    キャンセル

+1

一部jQueryで処理しているのでしょうか?
非同期の処理を実装したいなら$.whenや$.Deferredで対応してもいいかもしれません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/19 21:06

    ご回答ありがとうございました!
    $.whenという方法を用いてみましたが、途中でエラーになってしまいました(多分にこちらで書いたコードの問題であると思います)。ただ$.whenという方法は後にすぐ役立ちそうで、とても勉強になる情報でありましたのでメモして保存致しました。ありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • JavaScript

    17584questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    7122questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • Monaca

    1011questions

    「Monaca」はiOS、Android、Windows向けのアプリ開発に対応した、Cordovaベースのモバイルアプリ開発プラットフォームです。HTML5、JavaScriptといったWeb標準技術を用いてモバイルアプリ開発を行うことができます。

  • Cordova

    441questions

    Cordovaは様々なデバイスで使うことができるオープンソースなモバイル用開発プラットフォームです。開発者に各デバイスの元のプラットフォームで開発する必要をなくし、HTML・JavaScript・CSSなどの一般的なウェブのテクノロジーを使ってすべてのデバイスで展開することができるモバイルのアプリケーションを生成することを可能にします。