介紹
async 和 await結合可以以同步代碼程式設計方式書寫異步代碼。
async函數的隐式傳回值是Promise(許諾)對象。(見es6 promise)
await表達式:
- await必須寫在async函數中。
- await右邊的表達式必須是promise對象。
- await傳回的是promise成功的值,失敗時抛出異常。
原理
async/await的使用是把函數暫停了,當執行到await時,函數暫停執行,直到await等待的Promise狀态改變時回到這個函數執行。
協程
協程是跑線上程上的任務,一個線程上可以有多個協程,但是一個線程同時隻能執行一個協程。
生成器
前面帶有關鍵字的一個函數可以暫停執行或者恢複執行。在函數内部可以使用yield關鍵字來暫停函數的執行,切換到外部函數,其實就是協程的切換。在外部函數中可以通過調用next()方法來恢複函數的執行。
async/await原理
async隐式傳回Promise對象
代碼執行梳理
async function foo() {
console.log(1);
const result = await new Promse((reslove, reject) => {
resolve(2);
});
console.log(result);
}
console.log(3);
foo();
console.log(4);
代碼執行結果
- 程式在一個線程上執行,一個線程可以建立多個協程。
- 父協程列印3。
- 執行foo函數。由于foo函數被async标記過,是以當進入該函數的時候,JavaScript 引擎會建立一個協程。線程切換到foo函數子協程。
- 執行子協程列印2。
- 将Promise的異步任務放入任務隊列中執行。通過await關鍵詞利用生成器原理暫停子協程的運作。将await後面的Promise對象,傳回給父協程。
- 父協程答應4。
- 父協程等待await後面的Promise對象的執行結果,當Promise對象執行狀态變為完成時,調用Promise對象的then方法。then方法,将運作生成器原理的next将協程由父協程切換到子協程繼續運作,列印Promise的傳回值2。
js程式的執行順序
- 執行目前線程程式。遇到特殊函數會建立線程中的協程。将其他函數放到任務隊列中。
- 線程程式執行完。
- 執行任務隊列中的程式。
例子
async function main() {
let value1 = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve("執行成功1");
//reject("執行失敗1");
}, 3000);
});
console.log(1);
let value2 = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve("執行成功2");
//reject("執行失敗1");
}, 3000);
});
console.log(2);
console.log(value1 + value2);
}
main();