如何重新排序异步函数的执行

如何重新排序异步函数的执行

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

最佳答案

由于您已经在使用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);
            }
        });
};

关于javascript - 如何重新排序异步函数的执行?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18676754/

10-09 20:29