0
0

More than 3 years have passed since last update.

forの中で非同期処理関数の引数に変数iをもたせたいとき

Last updated at Posted at 2019-12-20

forの変数iを非同期処理の関数の引数として渡したい

問題のコード

なんのこっちゃという見出しですが、まずはこちらを見てください。

script.js
tokumei()
.then(function () { // 成功にたどりかない&失敗にもいかない
    console.log('成功');
}, function () {
    console.log('失敗');
});

function tokumei () {
    var paramList = [];
    var d = new $.Deferred();

    // paramListになにがしかをpushする処理(中略)

    for (var i = 0; i < paramList.length; i++) {
        ajaxFunc(paramList[i]) // ajax関数の呼び出し
        .then(function () {
            if (paramList.length === i + 1) d.resolve(); // resolveされない。
        }, function () {
            d.reject();
        });
    }
    return d.promise();
}

function ajaxFunc(param) {
    var d = new $.Deferred();
    var url = '/api/nanikanoapi?=' + param;

    setTimeout(function () {
        $.ajax({
                url: url,
                dataType: 'jsonp',
                cache: false,
                timeout: 10000
            })
            .done(function (data) {
                if (parseInt(data['response_code']) !== 400){
                    d.resolve();
                } else {
                    d.reject();
                }
            })
            .fail(function () {
                d.reject();
            });
    }, 200);

    return d.promise();
}

これ、動きません。
// resolveされないんです。
変数iが意図したように渡せません。

解決策

forの中で即時関数を実行してクロージャーを生成、引数にiを指定して渡してあげればOKでした。

正解のコード

script.js
tokumei(PDS)
.then(function () {
    console.log('成功'); // 成功にたどり着く
}, function () {
    console.log('失敗');
});

function tokumei () {
    var paramList = [];
    var d = new $.Deferred();

    // paramListになにがしかをpushする処理(中略)

    for (var i = 0; i < paramList.length; i++) {
        (function (i) { // クロージャー生成
            ajaxFunc(paramList[i]) // ajax関数の呼び出し
            .then(function () {
                if (paramList.length === i + 1) d.resolve(); // resoleveされた!
            },function(){
                d.reject();
            });
        })(i);
    }
    return d.promise();
}

function ajaxFunc(param) {
    var d = new $.Deferred();
    var url = '/api/nanikanoapi?=' + param;

    setTimeout(function () {
        $.ajax({
                url: url,
                dataType: 'jsonp',
                cache: false,
                timeout: 20000
            })
            .done(function (data) {
                if (parseInt(data['response_code']) !== 400){
                    d.resolve();
                } else {
                    d.reject();
                }
            })
            .fail(function () {
                d.reject();
            });
    }, 200);

    return d.promise();
}

ざっくりした書き方ですが、こんなかんじでいけました!

0
0
0

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
0
0