前言
前端網站初始化常需要透過一個或多個$.Ajax先跟後端要取資料,
你可以想像$.Ajax是送出去的一隻鴿子,
每一隻鴿子都有自己的目標地,腳下裝著要帶給後端的訊息,
這些鴿子訪問完目標地後,會把你需要的資料帶回來,讓你顯示在前端網頁上,
但你不太確定這些鴿子什麼時候回來,
你也不確定這些鴿子是否會帶回正確的資料(假如後端程式出錯),
你網站初始化時,不太可能等這些鴿子都回來再繼續下一個步驟,
$.when配合$.Deferred()
透過JQuery的$.when配合$.Deferred()完成多個$.ajax的異步處理,
當鴿子送出去後,你可以先執行其他的程式碼,
當鴿子回來後,再利用鴿子帶回的資料執行部分程式碼,
控制這群鴿子回來時,如果資料正確則做什麼、如果產生錯誤則做什麼,及不管如何皆執行什麼,
1 | $.when(function1(), function2()).done(function(result1, result2) { |
$.Deferred()控制返回
這裡可以看到$.ajax常使用$.Deferred()來控制返回時的各種狀況,
$.Deferred有一個狀態的概念:
- 使用$.Deferred.resolve(),將狀態更改為resolved,此時$.when就會執行done裡面的程式碼,
- 使用$.Deferred.reject(),將狀態更改為rejected,此時$.when就會執行fail裡面的程式碼,
- 最後JQuery官方建議使用return $.Deferred.promise(),防止其他程式變更這個狀態,結束這個function的呼叫,
另外
我們也可以直接宣告一個$.Deferred物件,來控制某段程式執行後,
當你不確定他什麼時候完成,但有一片段,需要等他完成後才來執行的情形,
1 | var alertFun = function(){ |
結語
- task來模擬那個不確定什麼時候完成的任務,假設需要五秒時間執行,故繼續執行$when之後的alert(‘第二個執行’)。
- 五秒後繼續執行task方法,遇到dtd.resolve,代表Deferred對象執行完畢可跳到done內。
- done執行的function()參數等於dtd.resolve()放入參數。
- return dtd.promise()後面的程式碼不會執行,dtd.resolve()後的程式碼會執行。
- 如果拿掉$.Deferred(),他執行完alertFun()裡面的程式,會被視為resolved狀態,不會等待五秒後遇到dfd.resolve()才執行done(),而是立刻執行,但此時你的五秒任務(也許是要資料)尚未完成。