1
if (option == 'Follow All') {
    for (var i = 0; i < userArray.length; i++) {
        followUser(params..);
    }

    // How to get this part to execute after followUser is done? (Basically when the for loop finishes)
    alert("There was a problem processing your request on Twitter to follow the following users: " + $('#errored-users').val());
    $('#errored-users').val('');
}

これを最初に複数回呼び出して、終了するのを待つにはどうすればよいですか?

var followUser = function(params..) {
    $.post('/api/1.0/followUser.php', {
        'user_to_follow': username,
        'username': user
    }).done(function(data) { {
            if (!is_batch) {
                alert("There was a problem processing your request on Twitter to follow @" + username);
            } else {
                //This currently gets executed last?
                var names = $('#errored-users').val();
                if (names == "") {
                    names = '@' + username + ', ';
                } else {
                    names += '@' + username + ', ';
                }
                $('#errored-users').val(names);
            }
};
4

4 に答える 4

1

すでに jQuery を使用しているため、AJAX 要求/約束を簡単に使用して、それらすべてが完了するのを待つことができます。$.whenこれであなたを大いに助けることができます:

var followUser = function(params..) {
    // return the promise!
    return $.post('/api/1.0/followUser.php', { ... });
};

if (option == 'Follow All') {
    var promises = [];
    for (var i = 0; i < userArray.length; i++) {
        promises.push(followUser(...));
    }

    $.when.apply(null, promises)
    .done(function() {
        // all users were successfully followed
    })
    .fail(function() {
        // at least one follow failed; no information about the others
        alert("There was a problem processing your request...");
        $('#errored-users').val('');
    });
}

これにより、すべてのリクエストが完了するとハンドラーが呼び出されますが、1 つだけが失敗するとすぐにハンドラーが呼び出さ.doneれます。.fail

代わりに、すべてのリクエストが完了した後 (成功または失敗) にハンドラーを実行する場合は、次のように、より手動で実行する必要があります。

var followUser = function(params..) {
    // return the promise!
    return $.post('/api/1.0/followUser.php', { ... });
};

if (option == 'Follow All') {
    var outcomes = { done: [], failed: [] };
    var total = userArray.length;
    function allFinished() {
         return outcomes.done.length + outcomes.failed.length == total;
    }

    for (var i = 0; i < total; i++) {
        followUser(...)
        .done(function() {
            outcomes.done.push(username);
        })
        .fail(function() {
            outcomes.failed.push(username);
        })
        // this must come last
        .always(function() {
            if (allFinished) {
                // outcomes contains the results
            }
        })
    }
}

これは、Twitter の HTTP 応答コードに基づく、要求の成功または失敗に関する jQuery の概念を引き続き使用します。この動作をカスタマイズしたい場合は、次followUserのように修正できます。

var followUser = function(params..) {
    return $.post('/api/1.0/followUser.php', { ... })
        .then(
        // first argument handles HTTP response successes, but you can
        // convert them to failures here:
        function(data) {
            if (convertSuccessToFailure) {
                return $.Deferred.reject(data);
            }
        });
};
于 2013-09-07T19:03:52.070 に答える
0

jQuery 1.5では、どの$.ajax関数ファミリーもpromise を返します。複数の promise を組み合わせて、すべての子 promise が解決されたときに解決される新しい promise を使用でき$.whenます。

function followUser(/* params */) {
    return $.post('/api/1.0/followUser.php', {
            user_to_follow: username,
            username: user
        });
}

var userRequests = [];
for (var i = 0, l = userArray.length; i < l; i++) {
    userRequests.push(followUser(/* params */));
}
$.when.apply($, userRequests).then(function(data) { /* etc. */ });
于 2013-09-07T19:04:59.330 に答える
0

followUser の呼び出し回数を保持するグローバル変数を定義できます。

if (option == 'Follow All') { var countUsers = userArray.length; for (var i = 0; i < countUsers; i++) { followUser(params..); } }

次に、匿名関数を逆方向にカウントするように変更し、すべてのユーザーが完了したら最後のステートメントを実行します。

function(data) { if (!is_batch) { alert("Twitter で @ をフォローするリクエストの処理中に問題が発生しました" + ユーザー名); } else { (...) } countUsers--; if(countUsers == 0){ alert("Twitter で次のユーザーをフォローするリクエストの処理中に問題が発生しました: " + $('#errored-users').val()); $('#errored-users').val(''); } };

于 2013-09-07T19:05:32.847 に答える
0

これに対する潜在的な解決策は、Promisesを使用することです(詳細な説明については、こちらを参照してください)。これは、非同期コードを同期させることを効果的に可能にする Javascript の新しいスタイルのコーディングを提供します。(これは Promises を大幅に単純化したものです。詳しく説明している記事については、こちらを参照してください)。

使用できるさまざまな実装があります。私が最もよく使用するものは、https ://github.com/cujojs/when にあります。そのウィキ内で提供されている例は、promise の力を示しています (こちらを参照)。

when.js を使用したコードの基本的な概要は次のようになります。

if (option == 'Follow All') {
  var deferreds = [];
  for (var i = 0; i < userArray.length; i++) {
      deferreds.push(followUser(params..));
  }

  when.all(deferreds).then(function everythingWasFine(suceededUsernames) {
    //do something with the responses e.g.
    alert(succeededUsernames.length + ' users were followed');
  },
  function somethingWentWrong(failedUsernames) {
    alert("There was a problem processing your request on Twitter to follow the following users: " + failedUsernames.join(','));
  });
}

var followUser = function(params..) {
  var defer = when.defer();
  $.post('/api/1.0/followUser.php', {
    'user_to_follow': username,
    'username': user
  }).done(function(data) {
        if (failure) {
           defer.reject(username);
        } else {
           defer.resolve(username);
        }
   });
   return when.promise;
 };
于 2013-09-07T19:05:55.717 に答える