異步: 一段不連續(xù)的程序流徐钠,在未來不確定的事件發(fā)生的事情堰酿。
問題:編程表述 在一件異步事件 A 發(fā)生后執(zhí)行程序 B
發(fā)展:異步事件+回調(diào) -> 三方庫(消息驅(qū)動(dòng),Promise祖很,二次編譯) -> 標(biāo)準(zhǔn)Promise對(duì)象愿险,Generator函數(shù)颇蜡, async函數(shù)
// Promise
const promise = new Promise(function(resolve, reject) {
// 異步操作
const A = '異步事件'
if ( A/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise.then(function(value) {
// success
console.log('B')
}, function(error) {
// failure
});
// Generator
function* GeneratorAB() {
yield 'A';
yield 'B';
return 'ending';
}
const hw = GeneratorAB();
hw.next()
hw.next()
//async
function timeoutA(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function asyncAB(value, ms) {
await timeoutA(ms);
console.log(value);
}
asyncAB('B', 3000);
Promise,Generator,async三者的關(guān)系:
實(shí)際運(yùn)用過程中,使用 Promise 包裝異步事件辆亏,使用 async 函數(shù)控制流程风秤。
async 是 Generator 函數(shù)的語法糖
Promise 對(duì)象
Promise對(duì)象是一個(gè)構(gòu)造函數(shù),用來生成Promise實(shí)例扮叨。
Promise構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù)缤弦,該函數(shù)的兩個(gè)參數(shù)分別是resolve和reject。
Promise彻磁,簡單說就是一個(gè)容器碍沐,里面保存著某個(gè)未來才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果。從語法上說兵迅,Promise 是一個(gè)對(duì)象抢韭,從它可以獲取異步操作的消息薪贫。Promise 提供統(tǒng)一的 API恍箭,各種異步操作都可以用同樣的方法進(jìn)行處理。resolve 函數(shù)的作用是瞧省,將Promise對(duì)象的狀態(tài)從“未完成”變?yōu)椤俺晒Α保磸?pending 變?yōu)?resolved)扯夭,在異步操作成功時(shí)調(diào)用,并將異步操作的結(jié)果鞍匾,作為參數(shù)傳遞出去交洗。
reject 函數(shù)的作用是,將Promise對(duì)象的狀態(tài)從“未完成”變?yōu)椤笆 保磸?pending 變?yōu)?rejected)橡淑,在異步操作失敗時(shí)調(diào)用构拳,并將異步操作報(bào)出的錯(cuò)誤,作為參數(shù)傳遞出去梁棠。
then 方法可以接受兩個(gè)回調(diào)函數(shù)作為參數(shù)置森。第一個(gè)回調(diào)函數(shù)是Promise對(duì)象的狀態(tài)變?yōu)閞esolved時(shí)調(diào)用,第二個(gè)回調(diào)函數(shù)是Promise對(duì)象的狀態(tài)變?yōu)閞ejected時(shí)調(diào)用符糊。其中凫海,第二個(gè)函數(shù)是可選的,不一定要提供男娄。這兩個(gè)函數(shù)都接受Promise對(duì)象傳出的值作為參數(shù)行贪。
catch方法 用于指定發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)漾稀。
Generator 函數(shù)
Generator 函數(shù)是一個(gè)狀態(tài)機(jī),封裝了多個(gè)內(nèi)部狀態(tài)建瘫。
Generator 函數(shù)是一個(gè)普通函數(shù)崭捍,但是有兩個(gè)特征。一是啰脚,function關(guān)鍵字與函數(shù)名之間有一個(gè)星號(hào)缕贡;二是,函數(shù)體內(nèi)部使用yield表達(dá)式拣播,定義不同的內(nèi)部狀態(tài)晾咪。
調(diào)用 Generator 函數(shù),返回一個(gè)遍歷器對(duì)象贮配,代表 Generator 函數(shù)的內(nèi)部指針谍倦。以后,每次調(diào)用遍歷器對(duì)象的next方法泪勒,就會(huì)返回一個(gè)有著value和done兩個(gè)屬性的對(duì)象昼蛀。value屬性表示當(dāng)前的內(nèi)部狀態(tài)的值,是yield表達(dá)式后面那個(gè)表達(dá)式的值圆存;done屬性是一個(gè)布爾值叼旋,表示是否遍歷結(jié)束。Generator 函數(shù)返回的遍歷器對(duì)象沦辙,只有調(diào)用next方法才會(huì)遍歷下一個(gè)內(nèi)部狀態(tài)夫植,yield表達(dá)式就是暫停標(biāo)志。
next 方法運(yùn)行邏輯:
(1)遇到y(tǒng)ield表達(dá)式油讯,就暫停執(zhí)行后面的操作详民,并將緊跟在yield后面的那個(gè)表達(dá)式的值,作為返回的對(duì)象的value屬性值陌兑。
(2)下一次調(diào)用next方法時(shí)沈跨,再繼續(xù)往下執(zhí)行,直到遇到下一個(gè)yield表達(dá)式兔综。
(3)如果沒有再遇到新的yield表達(dá)式饿凛,就一直運(yùn)行到函數(shù)結(jié)束,直到return語句為止软驰,并將return語句后面的表達(dá)式的值涧窒,作為返回的對(duì)象的value屬性值。
(4)如果該函數(shù)沒有return語句碌宴,則返回的對(duì)象的value屬性值為undefined杀狡。
async 函數(shù)
- async 函數(shù)是 Generator 函數(shù)的語法糖。
async函數(shù)就是將 Generator 函數(shù)的星號(hào)()替換成async贰镣,將yield替換成await*呜象,僅此而已膳凝。 - async 內(nèi)置執(zhí)行器,執(zhí)行 async函數(shù) 直接輸出最終結(jié)果。
- 返回值是 Promise 對(duì)象
參考:阮一峰-ES6入門