async是什么?它有什么作用低葫?
ES2017標(biāo)準(zhǔn)中引入了async函數(shù),它是Generator函數(shù)的語法糖仍律。
它的出現(xiàn)嘿悬,主要是為了使異步操作變得更加的簡單和直觀。
基本用法
async函數(shù)返回的是一個(gè)Promise對象水泉,這一點(diǎn)極其重要善涨,可以使用then方法添加回調(diào)函數(shù),當(dāng)函數(shù)執(zhí)行的時(shí)候草则,一旦遇到await就會(huì)先返回钢拧,等到異步結(jié)束之后,再接著執(zhí)行函數(shù)體內(nèi)之后的操作炕横。
async function fn() {
// console.log(a);
return "hello";
}
fn().then(value => {
console.log(value);
}).catch((err) => {
// console.log('打印出錯(cuò)誤');
console.log(err)
})
async函數(shù)有多種使用形式
// 函數(shù)聲明
async function foo() {}
// 函數(shù)表達(dá)式
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(…);
// 箭頭函數(shù)
const foo = async () => {};
語法
async語法比較簡單源内,難點(diǎn)在于錯(cuò)誤處理機(jī)制。
async返回Promise對象
再次強(qiáng)調(diào)了7莸睢Dさ觥!async返回Promise對象!
async函數(shù)中return語句返回的值,會(huì)成為then方法回調(diào)函數(shù)的參數(shù)壁公。
async function f() {
return 'hello world';
}
f().then(v => console.log(v))
// "hello world"
async函數(shù)中如果發(fā)生錯(cuò)誤,就會(huì)導(dǎo)致Promise對象變成了reject狀態(tài)焚鲜。拋出的錯(cuò)誤對象會(huì)被catch方法回調(diào)函數(shù)接收到。
async function f() {
throw new Error('出錯(cuò)了');
}
f().then(
v => console.log(v),
e => console.log(e)
)
// Error: 出錯(cuò)了
Promise對象狀態(tài)的變化
async函數(shù)返回的Promise對象放前,必須等待內(nèi)部所有的await命令后面的Promise對象執(zhí)行完成之后忿磅,才會(huì)發(fā)生狀態(tài)改變,除非遇到return語句或者拋出錯(cuò)誤凭语。也就是說葱她,只有async函數(shù)內(nèi)部的異步操作執(zhí)行完成,才會(huì)去執(zhí)行then方法中指定的回調(diào)函數(shù)似扔。
async function getTitle(url) {
let response = await fetch(url);
let html = await response.text();
return html.match(/<title>([\s\S]+)<\/title>/i)[1];
}
getTitle('https://tc39.github.io/ecma262/').then(console.log)
// "ECMAScript 2017 Language Specification"
函數(shù)getTitle內(nèi)部有三個(gè)操作:抓取網(wǎng)頁吨些、取出文本、匹配頁面標(biāo)題炒辉。只有這三個(gè)操作全部完成豪墅,才會(huì)執(zhí)行then方法里面的console.log。
await命令
正常情況下面黔寇,await命令后面是一個(gè)Promise對象偶器,如果不是,會(huì)被轉(zhuǎn)換成一個(gè)立即resolve的Promise對象。
await命令后面的Promise對象如果變成reject狀態(tài)屏轰,則reject的參數(shù)會(huì)被catch方法的回調(diào)函數(shù)接收到颊郎。
async function f() {
await Promise.reject('出錯(cuò)了');
}
f()
.then(v => console.log(v))
.catch(e => console.log(e))
// 出錯(cuò)了
實(shí)戰(zhàn)
async function timeout(ms) {
await new Promise((resolve) => {
setTimeout(resolve, ms);
console.log(1);
});
}
async function asyncPrint(value, ms) {
await timeout(ms);
console.log(value)
}
asyncPrint('Hello', 1000)
async function fn() {
await new Promise((resolve, reject) => {
reject('出錯(cuò)了~');
})
}
fn().then((val) => {
console.log(val)
}).catch((err) => {
console.log(err)
})