回調(callback)是一個函數被作為一個參數傳遞到另一個函數裡,在那個函數執行完後再執行。
假定有兩個函數f1和f2,f2等待f1的執行結果,f1()–>f2();如果f1很耗時,可以改寫f1,把f2(箭頭函數)寫成f1的回調函數:
優點:簡單、友善、實用。
缺點:易形成回調函數地獄。如果我們隻有一個異步操作,用回調函數來處理是完全沒有任何問題的。。但是如果我們要嵌套很多個回調函數,問題就很大了,因為多個異步操作形成了強耦合,代碼将亂作一團,無法管理。這種情況被稱為"回調函數地獄"(callback hell)。
含義: Promise是異步程式設計的一種解決方案,
優點: Promise是鍊式程式設計,有效的解決了令人頭痛的回調地獄問題,Promise的結果有成功和失敗兩種狀态,隻有異步操作的結果,可以決定目前是哪一種狀态,外界的任何操作都無法改變這個狀态。
2.1 常用API
resolve 傳回異步操作成功的結果
reject 傳回異步操作失敗的結果
then 執行Promise狀态是成功的操作
catch 執行Promise狀态是失敗的操作
finally 不管Promise狀态是成功或失敗都執行的操作
2.2 Promise.all
Promise.all方法用于将多個 Promise 執行個體,包裝成一個新的 Promise 執行個體。
const p = Promise.all([p1, p2, p3])
p的狀态由p1、p2、p3決定,分成兩種情況。
(1)隻有p1、p2、p3的狀态都變成fulfilled,p的狀态才會變成fulfilled,此時p1、p2、p3的傳回值組成一個數組,傳遞給p的回調函數。
(2)隻要p1、p2、p3之中有一個被rejected,p的狀态就變成rejected,此時第一個被reject的執行個體的傳回值,會傳遞給p的回調函數。
采用事件驅動模式,任務的執行不取決代碼的順序,而取決于某一個事件是否發生。
監聽函數有:on,bind,listen,addEventListener,observe
舉例,為f1綁定一個事件(jquery寫法):f1.on(‘done’,f2);即當f1發生done事件,就執行f2。
優點:易了解,可綁定多個事件,每一個事件可指定多個回調函數,可以去耦合,有利于實作子產品化
缺點:整個程式都要變成事件驅動型,運作流程會變得不清晰
含義: Generator 函數是 ES6 提供的一種異步程式設計解決方案,文法行為與傳統函數完全不同。
基本用法:
特征:
function關鍵字與函數名之間有一個星号;
函數體内部使用yield表達式,定義不同的内部狀态;
通過next方法擷取每段狀态的傳回結果,上面分成4次執行了Gennrator函數。
第一次,擷取第一個yield函數的傳回結果并暫停,done:false,代表函數内的狀态還沒有執行結束;
第二次,同理;
第三次,擷取return 的傳回結果,done:true表示函數内的狀态已經執行完畢;
第四次,函數内已經沒有可以執行的狀态,所有傳回undfined,同時告訴函數内的狀态已經執行完畢;
如果函數内沒有return,在第三次時傳回undfined,done:true表示函數内的狀态已經執行完畢;
含義: async 函數是在ES2017 标準中引入的,async使得異步操作變得更加友善,其實他就是Generator 函數的文法糖
說明:
await指令隻能用在async函數之中,如果用在普通函數,就會報錯。
await後面是一個Promise對象,如get1 return出去的Promise執行個體;
如果不是 Promise 對象,就直接傳回對應的值,如直接傳回’111’。
若Promise 對象, 并且其以值 x 被 fulfilled, 則傳回值為 x.
Promise 對象, 并且其以異常 e 被 rejected, 則抛出異常 e
async函數傳回的 Promise 對象,必須等到内部所有await指令後面的 Promise 對象執行完,才會發生狀态 改變;
如果任何一個await語句後面的 Promise 對象變為reject狀态或遇到return,那麼整個async函數都會中斷執行。
await 在等待 Promise 對象時會導緻 async function 暫停執行, 一直到 Promise 對象決議之後才會 async function 繼續執行;
如果我們希望即使前一個異步操作失敗,也不要中斷後面的異步操作。這時可以将第一個await放在 try…catch結構裡面,這樣不管這個異步操作是否成功,第二個await都會執行。
優點: 相比Generator函數,async函數有如下四點改進
内置執行器: Generator 函數的執行必須靠next()進行每一次的子產品執行,async自帶執行器,隻需要和普通函數一樣調用即可執行
更好的語義:async表示函數裡有異步操作,await表示緊跟在後面的表達式需要等待結果。
傳回值是Promise: async函數的傳回值是 Promise 對象,可以用then方法指定下一步的操作;
而且async函數完全可以看做多個異步函數的操作,包裝成的一個 Promise 對象,而await指令就是内部then指令的文法糖,即Promise.all()的用法 ;
多個await指令後面的異步操作,如果不存在繼發關系,最好讓它們同時觸發。
參考文章(侵删)