深刻理解 async / await

1、認識async

ES7 提出的async函數,終於讓 JavaScript 對於異步操做有了終極解決方案。No more callback hellasync函數是 Generator函數的語法糖。使用 關鍵字 async 來表示,在函數內部使用 await來表示異步。html

先說一下async的用法,它做爲一個關鍵字放到函數前面,用於表示函數是一個異步函數,由於async就是異步的意思, 異步函數也就意味着該函數的執行不會阻塞後面代碼的執行。 寫一個async 函數bash

async function timeout() {
  return 'hello world';
}
複製代碼

2、語法

async 函數返回一個 Promise 對象異步

async 函數內部 return 返回的值。會成爲 then 方法回調函數的參數。async

async function timeout() {
   return 'hello world';
}

timeout().then((v) => {
   console.log(v)
})

複製代碼

若是 async 函數內部拋出異常,則會致使返回的 Promise 對象狀態變爲 reject 狀態。拋出的錯誤而會被 catch 方法回調函數接收到。函數

async function e(){
   throw new Error('error');
}
e().then(v => console.log(v))
.catch( e => console.log(e));
複製代碼

async 函數返回的 Promise 對象,必須等到內部全部的 await 命令的 Promise 對象執行完,纔會發生狀態改變post

也就是說,只有當 async 函數內部的異步操做都執行完,纔會執行 then 方法的回調。ui

const delay = timeout => new Promise(resolve=> setTimeout(resolve, timeout));
async function f(){
    await delay(1000);
    await delay(2000);
    await delay(3000);
    return 'done';
}

f().then(v => console.log(v)); // 等待6s後才輸出 'done'
複製代碼

正常狀況下,await 命令後面跟着的是 Promise ,若是不是的話,也會被轉換成一個 當即 resolvePromise 以下面這個例子:spa

async function f() {
    return await 1
};
f().then( (v) => console.log(v)) // 1
複製代碼

3、Async 函數的錯誤處理

先來看下面的例子:code

let a;
async function f() {
    await Promise.reject('error');
    a = await 1; // 這段 await 並無執行
}
f().then(v => console.log(a));
複製代碼

當 async 函數中只要一個 await 出現 reject 狀態,則後面的 await 都不會被執行。解決辦法:能夠添加 try/catch。htm

// 正確的寫法
let a;
async function correct() {
    try {
        await Promise.reject('error')
    } catch (error) {
        console.log(error);
    }
    a = await 1;
    return a;
}
correct().then(v => console.log(a)); 
複製代碼

參考文章

理解 async/await

用 async/await 來處理異步

相關文章
相關標籤/搜索