在與後台實現資料互動時經常會遇到一種這樣的情況:
1.需要用一個ajax請求後台資料,並且要在擷取到資料之後再渲染到頁面,這個時候就必須用同步(async:false)。
2.然而在這個時候就會有另一種情況,當ajax的請求花費的時間比較長的時候需要一個loading層來顯示等待狀態
3.這個時候beforeSend是沒有效果的,即使把loading的代碼寫在ajax之前也不行。
4.原因就是ajax的async設定為false時瀏覽器的渲染(UI)線程和js線程是互斥的,在執行js耗時操作時,頁面渲染會被阻塞掉。當我們執行非同步ajax的時候沒有問題,但當設定為同步請求時,其他的動作(ajax函數後面的代碼,還有渲染線程)都會停止下來。即使我的DOM動作陳述式是在發起請求的前一句,這個同步請求也會“迅速”將UI線程阻塞,不給它執行的時間。這就是代碼失效的原因。
5.解決方案使用jquery的$.Deferred()和$.when().done()來實現非同步下達到同步執行的效果(注意:是在非同步下實現的):如圖
function getAjaxData () { var defer = $ .Deferred (); $ .ajax ({ url : '' , type : 'post' , data : '' , async : true , dataType : 'json' , success : function (data ) { defer .resolve (data ); } }); return defer ; } // 執行 $ ( '#id' ).click ( function () { showLoading (); // 顯示等待表徵圖 $ .when (getAjaxData ()).done ( function (data ) { closeLoading (); // 隱藏等待表徵圖 console .log (data ); // 執行其他代碼 }); });
相關連結:
http://www.cnblogs.com/lvdabao/p/3744030.html
http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html