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('');
    });
}

这将.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
            }
        })
    }
}

这仍将使用 jQuery 的请求成功或失败的概念,该概念基于 Twitter 的 HTTP 响应代码。如果您想自定义此行为,您可以修改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 使用以下方法解决时,该 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 。它的 wiki 中提供的示例展示了 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 回答