ES6 async函數
目錄
- ES6 async函數
-
- 基本用法
- async的特點
- 使用注意點
- 錯誤處理
- 三種方法寫異步
基本用法
ES2017 标準引入了 async 函數,使得異步操作變得更加友善
async函數是什麼?一句話,它就是Generator函數的文法糖
async 函數寫法
// 函數聲明
async function foo() {};
// 函數表達式
const foo = async function () {};
// 對象的方法
let obj = { async foo() {} };
obj.foo().then(...)
// Class 的方法
class Storage {
constructor() {
this.cachePromise = caches.open('avatars');
}
async getAvatar(name) {
const cache = await this.cachePromise;
return cache.match(`/avatars/${name}.jpg`);
}
}
const storage = new Storage();
storage.getAvatar('jake').then(…);
// 箭頭函數
const foo = async () => {};
回到頂部 目錄
讀取兩個檔案:
const fs = require('fs');
const readFile = function (fileName) {
return new Promise(function (resolve, reject) {
fs.readFile(fileName, function (error, data) {
if (error) return reject(error);
resolve(data);
});
});
};
// Generator 函數寫法
const gen = function* () {
const f1 = yield readFile('aa');
const f2 = yield readFile('bb');
console.log(f1.toString());
console.log(f2.toString());
};
// async 函數寫法
const asyncFile = async function () {
const f1 = await readFile('aa');
const f2 = await readFile('bb');
console.log(f1.toString());
console.log(f2.toString());
};
分析async函數實作過程:
- 通過async關鍵字,表明該函數體内部是異步操作
- 調用該函數,遇到await就去任務隊列中執行異步操作,等到異步操作完成,在執行函數體後面的語句
- 傳回Promise對象
- 任何await語句後面的Promise對象變為reject狀态,那麼整個async函數都會中斷執行
回到頂部 目錄
async的特點
- 不需要像Generator去調用next()方法
- async傳回的總是Promise對象,可以用then方法進行下一步操作
- async取代Generator函數的星号*,await取代Generator函數的yield
- co子產品約定,yield指令後面隻能是 Thunk 函數或 Promise 對象,而async函數的await指令後面,可以是 Promise 對象和原始類型的值(數值、字元串和布爾值,但這時會自動轉成立即 resolved 的 Promise 對象)
使用注意點
- await指令後面的Promise對象,運作結果可能是rejected,是以最好把await指令放在try…catch代碼塊中
- 多個await指令後面的異步操作,如果不存在繼發關系,最好讓它們同時觸發
- await指令隻能用在async函數之中,如果用在普通函數,就會報錯
- async 函數可以保留運作堆棧
錯誤處理
async function myFunction() {
try {
await errfn();
} catch (err) {
console.log(err);
}
}
// 另一種寫法
async function myFunction() {
await errfn()
.catch(function (err) {
console.log(err);
});
}
回到頂部 目錄
三種方法寫異步
var p = (val, isReject) =>{
return new Promise((res,rej) =>{
if(isReject){
setTimeout(rej, 1000, val);
}else{
setTimeout(res, 1000, val);
}
})
}
// Promise對象方法
var p2 = new Promise((res, rej) => {
p('one', false).then().then(val =>{
console.log(val)
})
})
// Generator 函數
var genP = function* (){
yield p('two', false);
};
var gp = genP();
gp.next().value.then(val => {
console.log(val)
});
// async 函數
var asyncP = async function(){
var ap = await p('three', false);
return ap;
}
asyncP().then(val =>{
console.log(val)
})
回到頂部 目錄