async函數(shù)是使用async
關(guān)鍵字聲明的函數(shù)朵夏。 async函數(shù)是AsyncFunction
構(gòu)造函數(shù)的實(shí)例池充, 并且其中允許使用await
關(guān)鍵字蚤告。async
和await
關(guān)鍵字讓我們可以用一種更簡潔的方式寫出基于Promise
的異步行為酥宴,而無需刻意地鏈?zhǔn)秸{(diào)用promise
锅论。
async
- async函數(shù)返回一個(gè)promise對象
async function fn () {
return 'async 函數(shù)'
}
console.log(fn());
image.png
- async倾哺,異步的意思糠爬,表示不會(huì)阻塞后面的同步代碼,因?yàn)槭莗romise對象寇荧,我們用then來獲取數(shù)據(jù)
async function fn () {
return 'async 函數(shù)'
}
fn().then(value => {
console.log(value);
})
console.log('我會(huì)先執(zhí)行');
image.png
- 處理異常,如果函數(shù)內(nèi)部有返回一個(gè)值,內(nèi)部會(huì)調(diào)用
Promise.resolve
函數(shù)返回值执隧,如果拋出錯(cuò)誤揩抡,內(nèi)部會(huì)調(diào)用Promise.reject
函數(shù),返回錯(cuò)誤信息镀琉;我們可以用catch
方法接受這個(gè)錯(cuò)誤信息
async function fn (flag) {
if (flag) {
return 'success'
} else {
throw 'fail'
}
}
console.log(fn(true)); //Promise {<fulfilled>: 'success'}
console.log(fn(false)); //Promise {<rejected>: 'fail'}
fn(false).then(value => {
console.log(value);
}).catch (e => {
console.log(e); //fail
})
await
await操作符必須寫在async函數(shù)內(nèi)部峦嗤,否則會(huì)報(bào)錯(cuò)
用于等待一個(gè)
Promise
對象或者任何要等待的值返回 Promise 對象的處理結(jié)果。如果等待的不是 Promise 對象滚粟,則返回該值本身寻仗。
await操作符會(huì)暫停當(dāng)前async函數(shù)的執(zhí)行,等待promise執(zhí)行結(jié)束
//若正常處理(fulfilled)
async function fn () {
let f = await Promise.resolve(100)
console.log(f); //100
}
fn()
//若拋出異常(rejected)
async function fn () {
try {
await Promise.reject('出錯(cuò)了')
} catch (e) {
console.log(e); //出錯(cuò)了
}
}
fn()
//如果返回值不是promise,會(huì)當(dāng)作正常處理的值返回
async function fn () {
let f = await 20
console.log(f); //20
}
fn()
使用場景
我們會(huì)在什么場景下使用async,await
?
- promise解決了回調(diào)地獄的問題凡壤,而
async,await
來進(jìn)一步優(yōu)化它 - 處理多重then方法的調(diào)用
var num = function (n) {
return new Promise ((resolve, reject) => {
setTimeout(resolve, n, n * 10)
})
}
let step1 = function (n) {
console.log('step1 ' + n);
return num(n)
}
let step2 = function (n) {
console.log('step2 ' + n);
return num(n)
}
let step3 = function (n) {
console.log('step3 ' + n);
return num(n)
}
//使用then鏈處理
function deal () {
var n1 = 10
step1(n1).then(n2 => step2(n2))
.then(n3 => step3(n3))
.then(res => res)
}
deal()
//使用`async,await`處理
async function deal () {
let n1 = 10
let n2 = await step1(n1)
let n3 = await step2(n2)
let res = await step3(n3)
return res
}
deal()
可以明顯看出使用async,await
之后署尤,我們可以像使用同步代碼一樣處理異步任務(wù),體驗(yàn)更佳