回調函數,或簡稱回調,是指通過函數參數傳遞到其它代碼的,某一塊可執行代碼的引用。這一設計允許了底層代碼調用在高層定義的子程式。 咋一看回調函數的概念,可能並不能立即理解什麼是回調函數。通俗的講,回調函數就是以函數作為參數傳給另一個函數執行。比如:有一個函數A,函數B, 將A函數作為B函數的參數,然... ...
一、概念
回調函數,或簡稱回調,是指通過函數參數傳遞到其它代碼的,某一塊可執行代碼的引用。這一設計允許了底層代碼調用在高層定義的子程式。
咋一看回調函數的概念,可能並不能立即理解什麼是回調函數。通俗的講,回調函數就是以函數作為參數傳給另一個函數執行。比如:有一個函數A,函數B,
將A函數作為B函數的參數,然後在B函數里執行A函數,這就是最簡單的回調。
var A = function(){ console.log("我是回調函數A。"); }; var B = function(callback){ console.log("我是主函數B內的代碼。"); callback(); }; B(A);
這下大伙應該能理解什麼是回調了吧。估計大伙會想,這樣的回調有意義嗎?把A函數的代碼直接寫到B函數裡面不是更好嗎?
如果在實際項目里這樣寫回調真的是糟糕透了。往下看,瞭解回調是如何應用的。
二、同步回調和非同步回調
什麼,回調不是非同步的嗎?仔細看看上面的例子,大家就能明白,回調不一定都是非同步的,他有同步和非同步之分。上面的示例就是一個同步回調,
所以我不想在過多的解釋什麼是同步回調,接下來,我們看看什麼是非同步回調。
由於 JS 是單線程的,一旦我們要執行一個長耗時的任務時,如果一直單線程的堵塞下去會導致程式的等待時間過長而使頁面失去響應,非常影響用戶體驗。
為瞭解決這樣的問題,我們就可以使用非同步回調。將耗時的任務扔給非同步去做,做好了再通知下我們做完了,我們拿到數據繼續往下走。
下麵是 ajax 非同步請求的部分代碼:
var xhr; ...... xhr.onreadystatechange = function(){ if(xhr.readystate === 4 && xhr.status === 200){ //do something } }
當瀏覽器發起 ajax 請求的時候,會單開一個線程發起 http 請求,這樣就能把耗時的 http 請求獨自運行。在請求的過程中 readystate
的值會不斷的變化,對應著不同的請求狀態。大家看看 jquery 對 ajax 的封裝就能明白,它就是根據 readystate 返回的狀態,執行不
同的回調,最常用的兩個回調應該是 success 函數和 error 函數。
非同步回調的應用,如下,有 A 和 B 兩個函數:
//一般情況下,應該是這樣的 A(); B(); //當 A 函數是一個長耗時任務時,為瞭解決 A 函數長時間阻塞頁面問題 //可以將 B 函數作為 A 函數的回調執行 function A(callback){ setTimeout(function () { // A 的任務代碼 callback(); }, 3000); } A(B);
因為 JS 是單線程的,所以非同步回調也不是真正意義上的非同步,它只不過是一個偽非同步執行,它通常利用定時器和條件判斷來偽裝非同步執行。