前端多層回調問題解決方案之$.Deferred
阿新 • • 發佈:2017-09-02
fail -s 使用 defer 解決方法 == 默認 don blog
javascript引擎是單線程的,但是通過異步回調可以實現IO操作並行執行能力,當業務邏輯復雜的時候我們就進入回調地獄。
本文講得ajax是在jquery1.5以前的版本,目的旨在讓我們理解延遲對象的應用場景,jquery1.5之後,ajax默認就是延遲對象,可以進行鏈式操作
舉例:
a(funtion(){ b(funtion(){ c(funtion(){ d(funtion(){ e(funtion(){ f(funtion(){ g(funtion(){ finish(); }); }); }); }); }); }); });
這還是比較簡單的操作,如果每個回調函數還有N多操作,那麽更加頭疼了。
解決方法:通過jQuery的when().done()實現
1. 函數a,b,c,d,e,f,g都這樣寫
function a(){ var dtd = $.Deferred(); //這裏延遲操作,可能是ajax,也可能是setTimeout $.post(url,{},function(data){ .... alert("執行完畢!"); dtd.resolve(); // 改變Deferred對象的執行狀態 }) ; return dtd.promise(); }
2. 使用
$.when(
a(),
b(),
c(),
d(),
e(),
f(),
g()
).done(finish).fail() ;
PS: 除了$.when().done()組合,還有一種組合$.when().then()。
done是在when中的延遲對象dtd都resolve的時候才回執行done中的操作,then是延遲對象有一個resolve就執行。類似於“與”和“或”。
如上的例子,如果a函數裏面的ajax請求返回的不是我們想要的結果,我們不想讓done執行,應該怎麽做呢?
function a(){var dtd = $.Deferred(); //這裏延遲操作,可能是ajax,也可能是setTimeout $.post(url,{},function(data){ if(data == 1){ dtd.resolve(); // 改變Deferred對象的執行狀態 }else{ dtd.reject(); // 作用和resolve正好相反 } }); return dtd.promise(); }
如果a函數服務器返回的是1, 那麽done可以執行,如果不是1,那麽不會執行done,而是立即執行fail。
如果這裏是then那麽不會受到影響,只要a,b,c,d,e,f,g有一個resolve。
還有一個函數$when().always(),這個不管when中resolve還是reject,最後都會執行always。
文章轉自: http://www.myjscode.com/page/article10.html
前端多層回調問題解決方案之$.Deferred