async/await是一種方便使用promise的特殊語法。javascript
函數前面的async表示:此函數將會返回一個promise,若是函數返回的不是promise,將會包裝成一個已經resolved的promise。java
async function f() { return 1; } f().then(alert); // 1 // 至關於下面的寫法 async function f() { return Promise.resolve(1); } f().then(alert); // 1 複製代碼
await只在async函數中有效,普通函數中使用await會報語法錯誤。let value = await promise;
表示讓JavaScript引擎等待直到 promise 完成並返回結果。這個行爲不會耗費 CPU 資源,由於引擎能夠同時處理其餘任務:執行其餘腳本,處理事件等。promise
async function f() { let promise = new Promise((resolve, reject) => { setTimeout(() => resolve("done!"), 1000) }); let result = await promise; // 等待直到 promise resolved後拿到result繼續往下執行 alert(result); // "done!" } f(); 複製代碼
await能夠接收Thenable對象(具備 then 方法的對象)並調用then方法,並將resolve,reject 做爲參數傳入。而後await等到這兩個方法中的某個被調用,再處理獲得的結果。markdown
class Thenable { constructor(num) { this.num = num; } then(resolve, reject) { setTimeout(() => resolve(this.num * 2), 1000); } }; async function f() { // 等待 1 秒, result 變爲 2 let result = await new Thenable(1); alert(result); } f(); 複製代碼
若是想定義一個 async 的類方法,在方法前面添加 async 就能夠了:async
class Waiter { async wait() { return await Promise.resolve(1); } } new Waiter().wait().then(alert); // 1 複製代碼
若是一個promise被resolved,await promise返回的就是其結果。 若是一個promise被rejected,就會拋出一個錯誤,就像在那一行有個 throw 語句那樣。函數
async function f() { await Promise.reject(new Error("Whoops!")); } // 至關於: async function f() { throw new Error("Whoops!"); } 複製代碼
能夠用 try..catch 來捕獲上面的錯誤,就像對通常的 throw 語句那樣:oop
async function f() { try { let response = await fetch('http://no-such-url'); } catch(err) { alert(err); // TypeError: failed to fetch } } f(); 複製代碼
若是不使用 try..catch,由f() 產生的 promise 就會被reject,能夠在函數調用後添加 .catch 來處理錯誤。若是沒處理錯誤能夠使用全局的unhandledrejection事件來捕獲。fetch
async function f() { let response = await fetch('http://no-such-url'); } // f() 變爲一個被reject的 promise f().catch(alert); // TypeError: failed to fetch // (*) 複製代碼
當須要等待多個promise時,能夠用Promise.all搭配async/await使用:this
async () => { let results = await Promise.all([ fetch(url1), fetch(url2), ... ]); } 複製代碼
若是發生錯誤,也會正常傳遞:先從失敗的 promise 傳到 Promise.all,而後變成咱們能用 try..catch 處理的異常。url
Async/await 是基於 promise 的,因此它內部使用相同的微任務隊列,而且相對宏任務來講具備更高的優先級。
async function f() { return 1; } (async () => { setTimeout(() => alert('timeout'), 0); // 3 await f(); // 1 alert('await'); // 2 })(); 複製代碼
在一個普通的函數中,如何調用另外一個 async 函數而且拿到返回值?使用then,由於async函數返回一個settled promise。
async function wait() { await new Promise(resolve => setTimeout(resolve, 1000)); return 10; } (function() { wait().then((value) => alert(value)); })();複製代碼