ES7
提出的async
函數,終於讓 JavaScript
對於異步操做有了終極解決方案。No more callback hell
。async
函數是 Generator
函數的語法糖。使用 關鍵字 async
來表示,在函數內部使用 await
來表示異步。html
先說一下async的用法,它做爲一個關鍵字放到函數前面,用於表示函數是一個異步函數,由於async就是異步的意思, 異步函數也就意味着該函數的執行不會阻塞後面代碼的執行。 寫一個async 函數bash
async function timeout() {
  return 'hello world';
}
複製代碼
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 ,若是不是的話,也會被轉換成一個 當即 resolve
的Promise
以下面這個例子:spa
async function f() {
return await 1
};
f().then( (v) => console.log(v)) // 1
複製代碼
先來看下面的例子: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));
複製代碼
參考文章