2013-06-30 44 views
1

我有這樣一個循環:鏈排隊回調導致

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

function AllItemsLoaded() 
{ 
} 

我的目標是以後所有項目加載並執行在回調的代碼,例如執行AllItemsLoaded()在調用AllItemsLoaded()之前,應該調用每個項目回調並執行DoSomethingWithResult(),所有這些項目都是異步加載的。

我試過jQuery的遞延/管,看起來像這樣我的代碼:

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

回答

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()等待所有負載。

+0

我喜歡你的答案最多的,但我有一個問題。在調用resolve()之前立即執行AllItemsLoaded。 – Deepsy

+0

http://jsfiddle.net/5vcqQ/ <查看結果 – Deepsy

+0

@Deepsy我現在不在電腦上,但是我想什麼時候不用數組。我應該使用$ .when.apply。當我到達電腦時我會嘗試它。 –

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

的第一件事就是用.get().post()不​​,原因在於​​回報jQuery的,而其他兩個返回jqXHR(即承諾),這是你想要的這裏。

接下來的事情是提供一個數組來積累jqXHR的承諾。

最後,您需要知道如何讓$.when()作用於承諾數組,以便在所有這些承諾解決(或發生錯誤)時執行某些操作。

整個事情是這樣的:

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