天天看點

async await執行流程原了解析

介紹

async 和 await結合可以以同步代碼程式設計方式書寫異步代碼。

async函數的隐式傳回值是Promise(許諾)對象。(見es6 promise)

await表達式:

  1. await必須寫在async函數中。
  2. await右邊的表達式必須是promise對象。
  3. await傳回的是promise成功的值,失敗時抛出異常。

原理

async/await的使用是把函數暫停了,當執行到await時,函數暫停執行,直到await等待的Promise狀态改變時回到這個函數執行。

協程

協程是跑線上程上的任務,一個線程上可以有多個協程,但是一個線程同時隻能執行一個協程。

生成器

前面帶有關鍵字的一個函數可以暫停執行或者恢複執行。在函數内部可以使用yield關鍵字來暫停函數的執行,切換到外部函數,其實就是協程的切換。在外部函數中可以通過調用next()方法來恢複函數的執行。

async await執行流程原了解析

async/await原理

async隐式傳回Promise對象

代碼執行梳理

async await執行流程原了解析

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);

代碼執行結果

async await執行流程原了解析
  1. 程式在一個線程上執行,一個線程可以建立多個協程。
  2. 父協程列印3。
  3. 執行foo函數。由于foo函數被async标記過,是以當進入該函數的時候,JavaScript 引擎會建立一個協程。線程切換到foo函數子協程。
  4. 執行子協程列印2。
  5. 将Promise的異步任務放入任務隊列中執行。通過await關鍵詞利用生成器原理暫停子協程的運作。将await後面的Promise對象,傳回給父協程。
  6. 父協程答應4。
  7. 父協程等待await後面的Promise對象的執行結果,當Promise對象執行狀态變為完成時,調用Promise對象的then方法。then方法,将運作生成器原理的next将協程由父協程切換到子協程繼續運作,列印Promise的傳回值2。

js程式的執行順序

  1. 執行目前線程程式。遇到特殊函數會建立線程中的協程。将其他函數放到任務隊列中。
  2. 線程程式執行完。
  3. 執行任務隊列中的程式。

例子

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();

async await執行流程原了解析

繼續閱讀