LoginSignup
12
9

More than 5 years have passed since last update.

[JavaScript] forの中でコールバックが発生する場合は要注意

Last updated at Posted at 2015-07-22

forループの中で外部処理系からのコールバックが発生する場合は、ループ変数だけが一気に変化するので注意が必要です。 ここでいう『外部処理系からのコールバック』とは、たとえばAjax等を利用してWebからデータを取得したり、KiiCloud等を利用してmBaaSからデータを取得したりする場合を指します。

churippu_s.png 悪い例

JavaScript
// テスト用配列
var abc = ["a","b","c"];

// 悪い例
for(var i in abc) {
    // コールバックが発生する外部処理
    external(function() {
        alert(abc[i]); // c→c→c と3回表示されてしまう
    });
}
//============================================
// 外部処理系のつもり(Web接続、DB接続などを想定)
//============================================
function external(callback) {
    setTimeout(callback, 1000);
}

churippu_s.png 良い例1:ループ変数を受け取る関数でラップ

JavaScript
// 良い例1:ループ変数を受け取る関数でラップする
for(var i in abc) {
    wrap(i);
    function wrap(n) {
        // コールバックが発生する外部処理
        external(function() {
            alert(abc[n]); // a→b→c の順に正しく表示される(※)
        });
    }
}

(※)実際の外部処理系では順不同です

churippu_s.png 良い例2:例1を無名関数化

JavaScript
// 良い例2:ループ変数を受け取る無名関数でラップする
for(var i in abc) {
    (function(n) {
        // コールバックが発生する外部処理
        external(function() {
            alert(abc[n]); // a→b→c の順に正しく表示される(※)
        });
    })(i);
}

(※)実際の外部処理系では順不同です

churippu_s.png デモソース

デモソースはこちら

(・o・ゞ いじょー。

12
9
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9