2015-11-12 12 views
1

我在考慮如何更好地管理運行多個異步通話的順序以實現最佳週轉時間。基本上這個過程是這樣的: 當網頁開始加載時,它顯示頁面並啓動幾個AJAX調用a(),b()和c()。在這三個完成後,運行異步調用d()。我檢查了幾個線程,如jquery execute function when two conditions are met但這不完全相同。AJAX推出多個asyc通話完成時的最終asyc通話

我試圖使用多個標誌來顯示異步調用是否完成,以及一個阻止該過程的塊功能,直到可以拍攝最後一次調用。

var aFinished=false; 
function a() { 
     var jsonData = $.ajax({ 
     url: "${createLink(controller:'environment', action:'a')}", 
     dataType: "json", 
     async: true 
     }).done(function(jsonData) { 
      //do something 
      aFinished=true; 
    }); 
} 
//same flag+function for b() and c() 
function d(){ 
    blockTillAllDone(); 
    var jsonData=$.ajax(...).done(...); 
} 
function blockTillAllDone(){ 
    if(aFinished&&bFinished&&cFinished){ 
     console.log("Ok to continue"); 
     return; 
    } 
    else{ 
     console.log("Have to wait"); 
     setTimeout(blockTillAllDone(),2000); 
    } 
} 
a();b();c();d(); 

由於遞歸塊函數導致堆棧增長,性能並不是很好。有沒有人有更好的想法如何以更多的AJAX的方式實現這一點,而不是一個暴力破解功能? 在此先感謝!

回答

2

您正在尋找promises

This article做了很好的解釋基礎知識。儘管許多瀏覽器現在都支持它們(除了IE),但您仍然希望包含像es-6 promise這樣的polyfill。一旦你開始使用的承諾就可以解決你的問題,做這樣的事情:

var a = new Promise(function(resolve,reject){ 
    $.ajax({ 
     type: 'GET', 
     dataType: 'json', 
     url: 'example.com/test/1', 
     success: function(response){resolve(response);}, 
     error: function(response){reject(response);} 
    }); 
}); 

var b = new Promise(function(resolve,reject){ 
    $.ajax({ 
     type: 'GET', 
     dataType: 'json', 
     url: 'example.com/test/1', 
     success: function(response){resolve(response);}, 
     error: function(response){reject(response);} 
    }); 
}); 

var c = new Promise(function(resolve,reject){ 
    $.ajax({ 
     type: 'GET', 
     dataType: 'json', 
     url: 'example.com/test/1', 
     success: function(response){resolve(response);}, 
     error: function(response){reject(response);} 
    }); 
}); 

//This will run once all async operations have successfully finished 
Promise.all([a,b,c]).then(
    function(data){ 
     //everything successful, handle data here 
     displayData(data); 
    }, 
    function(data){ 
     //something failed, handle error here 
     logoutError(data); 
    } 
); 
+1

僅供參考:任何IE都不支持這個功能,即使是11 - http://caniuse.com/#search=promise –

+1

但IE問題可以通過使用[es6-promise](https:// github。 com/jakearchibald/es6-promise)正如答案中所述:) – ndd

+1

謝謝Victor!我剛剛編輯了我的答案,以使其更清楚。 –

1

您可以嘗試基於事件的方法。把每個檢查的完成方法a(),在一類b()c()以及如果三項都做,如果做的再提升,這將通過監聽器被捕獲的事件,然後它可以執行d()

我會盡量演示這使用代碼。

+0

換句話說:一個把d()在做(), b和c在aFinished && bFinish的檢查之後編輯&& cFinished。 d()將由最後完成的一個發射。我能幫你正確嗎?確實非常聰明的方式! – OrlandoL

1

移動檢查到d(),並在done(..)調用(除非你希望它的出現,無論它是成功還是失敗 - 在這種情況下使用always(..))的A,b和C

var aFinished=false; 
function a() { 
     var jsonData = $.ajax({ 
     url: "${createLink(controller:'environment', action:'a')}", 
     dataType: "json", 
     async: true 
     }).done(function(jsonData) { 
      //do something 
      aFinished=true; 
      d(); 
     }); 
} 
//same flag+function for b() and c() 
function d(){ 
    if(aFinished&&bFinished&&cFinished){ 
     var jsonData=$.ajax(...).done(...); 
    } 
} 

a();b();c(); 

那麼就沒有必要爲您的blockTillAllDonesetTimeout

+0

這實際上與@ndd提出的相同。確實快速而智能的解決方案但老實說,我只是好奇AJAX是否可以提供像$ .whenConditionMet({...})。ajax({...})的方式。 – OrlandoL