链排队回调结果

时间:2013-06-30 01:11:23

标签: javascript jquery asynchronous callback promise

我得到了一个这样的循环:

for ( var current in all )
{
    //load the item
    prepare.load( all[current].resource , function( result ) { 
         doSomethingWithResult(result);
    });
}

function AllItemsLoaded()
{
}

我的目标是在加载所有项目并执行回调中的代码后执行AllItemsLoaded(),例如,对于每个项目应该调用回调,并且在调用AllItemsLoaded()之前应该执行DoSomethingWithResult(),所有这些项都是异步加载的。

我尝试过Jquery Deferred / pipe,我的代码看起来像这样:

var chain = new $.Deferred().resolve();

for ( var current in all )
{
                chain = chain.pipe(function(res){
                prepare.load( all[current].resource , function( result ) { 
                     doSomethingWithResult(result);
                });
            });
 //if I do a return here, the pipe will continue without getting the result, 
so I need to continue the pipe after load's callback and 
doSomethingWithResult is executed

}

chain.done(AllItemsLoaded);

4 个答案:

答案 0 :(得分:2)

延期是一个好主意。但是,你需要等待承诺。这是一种方法,使用何时等待所有承诺而不按顺序执行:

var loads = [];

for ( var current in all )
{
        (function(){
    var deferred = new $.Deferred();
    prepare.load( all[current].resource , function( result ) { 
         doSomethingWithResult(result);
         deferred.resolve(result);
    });
    loads.push(deferred.promise());
        })();
}

$.when.apply(null, loads).then(AllItemsLoaded);

首先为每个负载创建一个新的延迟。将其承诺放在一个集合中。加载后,解决延迟。使用$ .when()等待所有负载。

答案 1 :(得分:1)

这是你需要的吗?

来自:http://aabs.wordpress.com/2009/12/16/sequential-script-loading-on-demand/

function LoadScriptsSequentially(scriptUrls, callback)
{
    if (typeof scriptUrls == 'undefined') throw "Argument Error: URL array is unusable";
    if (scriptUrls.length == 0 && typeof callback == 'function') callback();
    $.getScript(scriptUrls.shift(), function() { LoadScriptsSequentially(scriptUrls, callback); });
}

答案 2 :(得分:0)

我会这样做(下面),你用你自己的异步对象替换每个$.get(),用它自己的完整处理程序。

$(document).ready(function() {

    $.when( 
        $.get("ajax.php?a=b"), 
        $.get("ajax.php?a=c"), 
        $.get("ajax.php?a=d")                   
    ).then(
        function() {
                // both AJAX calls have succeeded
                alert("All Done");
        }, 
        function() {
                // one of the AJAX calls has failed
                alert("One or more failed");
        }
    );
});

答案 3 :(得分:0)

首先使用.get().post()而不是.load(),原因是.load()返回jQuery而其他两个返回jqXHR(即承诺),这就是你想要的。

接下来就是提供一个数组来累积jqXHR的承诺。

最后你需要知道如何让$.when()对Promise数组起作用,在所有这些都被解析(或发生错误)时做一些事情。

整件事看起来像这样:

var promises = [];//new Array

for ( var current in all ) {
    prepare.get( all[current].resource, function( result ) {
         doSomethingWithResult(result);
    });
}

$.when.apply(null, promises).then(AllItemsLoaded, myErrorHandler);