什么是回調(diào)函數(shù)艇抠?
回調(diào)函數(shù)是一個(gè)函數(shù)妒御,將會(huì)在另一個(gè)函數(shù)完成執(zhí)行后立即執(zhí)行樟氢「园恚回調(diào)函數(shù)是一個(gè)作為參數(shù)傳給另一個(gè)函數(shù)的函數(shù)。這個(gè)回調(diào)函數(shù)會(huì)在傳給的函數(shù)內(nèi)部執(zhí)行埠啃。
為什么我們需要回調(diào)死宣?
客戶端 JavaScript?在瀏覽器中運(yùn)行,并且瀏覽器的主進(jìn)程是單線程事件循環(huán)碴开。如果我們嘗試在單線程事件循環(huán)中執(zhí)行長(zhǎng)時(shí)間運(yùn)行的操作毅该,則會(huì)阻止該過程。從技術(shù)上講這是不好的潦牛,因?yàn)檫^程在等待操作完成時(shí)會(huì)停止處理其他事件眶掌。
在上面的代碼片段中,首先執(zhí)行g(shù)etMessage()函數(shù)巴碗,然后執(zhí)行displayMessage()朴爬。兩者都在瀏覽器的控制臺(tái)窗口中顯示了一條消息,并且都立即執(zhí)行橡淆。
在某些情況下召噩,一些代碼不會(huì)立即執(zhí)行。例如逸爵,如果我們假設(shè)getMessage()函數(shù)執(zhí)行 API 調(diào)用具滴,則必須將請(qǐng)求發(fā)送到服務(wù)器并等待響應(yīng)。這時(shí)我們應(yīng)該如何處理呢师倔?
如何使用回調(diào)函數(shù)抵蚊?
為了使用回調(diào)函數(shù),我們需要執(zhí)行某種無(wú)法立即顯示結(jié)果的任務(wù)溯革。為了模擬這種行為贞绳,我們用 JavaScript 的setTimeout()函數(shù)。該函數(shù)會(huì)暫停兩秒鐘致稀,然后在控制臺(tái)窗口中顯示消息“ Hi冈闭,there”。
“顯示的消息”將被顯示在瀏覽器的控制臺(tái)窗口中抖单。在這種情況下萎攒,首先遇八,我們需要等待getMessage()函數(shù)。成功執(zhí)行此函數(shù)后耍休,再執(zhí)行displayMessage()函數(shù)刃永。
回調(diào)的工作方式
從上一個(gè)例子可以看到,在getMessage()函數(shù)中羊精,我們傳遞了兩個(gè)參數(shù)斯够。第一個(gè)參數(shù)是msg變量,該變量顯示在瀏覽器的控制臺(tái)窗口中喧锦,第二個(gè)參數(shù)是回調(diào)函數(shù)读规。
現(xiàn)在,你可能想知道為什么將回調(diào)函數(shù)作為參數(shù)進(jìn)行傳遞 —— 要實(shí)現(xiàn)回調(diào)函數(shù)燃少,我們必須將一個(gè)函數(shù)作為參數(shù)傳給另一個(gè)函數(shù)束亏。
在getMessage()完成任務(wù)后,我們將調(diào)用回調(diào)函數(shù)阵具。之后碍遍,當(dāng)調(diào)用getMessage()函數(shù)時(shí),將引用傳給displayMessage()函數(shù)阳液,該函數(shù)就是回調(diào)函數(shù)怕敬。
注意,當(dāng)調(diào)用getMessage()函數(shù)時(shí)趁舀,我們僅將其引用傳給displayMessage()函數(shù)赖捌。這就是為什么你不會(huì)在它旁邊看到函數(shù)調(diào)用運(yùn)算符,也就是()符號(hào)矮烹。
Javascript 回調(diào)地獄
當(dāng)多個(gè)異步函數(shù)一個(gè)接一個(gè)地執(zhí)行時(shí)越庇,會(huì)產(chǎn)生回調(diào)地獄。它也被稱為厄運(yùn)金字塔奉狈。
如何避免回調(diào)地獄卤唉?
可以使用多種技術(shù)來(lái)避免回調(diào)地獄,如下所示仁期。
使用promise
借助 async-await
使用 async.js 庫(kù)