工作中经常用到Async/await,但是具体实现原理并不是很懂。通过学习手撕Async/await
Async是什么
- async函数是使用
async关键字声明的函数。 async函数是AsyncFunction构造函数的实例, 并且其中允许使用await关键字。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。 - developer.mozilla.org/zh-CN/docs/…
使用Async/await
// promise函数
function resolveFn() {
return new Promise(resolve => {
setTimeout(() => {
resolve('ok')
}, 1000)
})
}
// async函数
async function asyncCall() {
console.info('calling')
const result = await resolveFn()
console.info(result)
return result
}
const pro = asyncCall()
// 打印'calling'
// 返回Promise对象,{PromiseState: 'fulfilled', PromiseResult: undefined}
// 1s后打印 'ok',Promise对象状态和值更新
使用Async/await
- Async函数返回的是Promise对象,返回结果根据执行的返回值确定
- await表达式必须写在Async函数中
- await右侧是Promise对象或其他值
- await失败了会抛出异常,需要try...catch获取
了解Generator/yild
Async/await是语法糖,基于Generator/yild函数封装的
function resolveFn(data) {
return new Promise(resolve => {
setTimeout(() => {
resolve(data * 10)
}, 1000)
})
}
// Generator函数
function* genFn() {
// 中途暂停点
yield resolveFn(1)
yield resolveFn(2)
return 'result'
}
// 逐步获取值
const gen = genFn()
console.info(gen.next()) // 打印 {value: Promise{<fulfilled>:10}, done: false}
console.info(gen.next()) // 打印 {value: Promise{<fulfilled>:20}, done: false}
console.info(gen.next()) // 打印 {value: 'result', done: true} // vaule为return返回值,done状态为true
// Generator函数2
function* genFn2() {
// 中途暂停点
const res1 = yield resolveFn(1)
// 传入上一个yield的参数
const res2 = yield resolveFn(res1)
return res2
}
// then方法调用
const gen2 = genFn2()
gen2.next().value.then(res1 => {
console.info(res1)
gen2.next(res1).value.then(res2 => {
console.info(res2)
console.info(gen2.next(res2))
})
})
// 1s打印10
// 2s打印100
// 2s打印{value: 100, done: true}
封装Async/await
// Promise函数
function resolveFn(data) {
return new Promise(resolve => {
setTimeout(() => {
resolve(data * 10)
}, 1000)
})
}
// Generator函数
function* genFn() {
const num1 = yield resolveFn(1)
console.info(num1) // 1s后打印10
const num2 = yield resolveFn(num1)
console.info(num2) // 2s后打印100
return num2
}
// 处理函数
function AsyncFunction(fn) {
const gen = fn()
return new Promise((resolve, reject) => {
function go(arg){
let res
// 执行Generator函数获取next结果
try {
res = gen.next(arg)
} catch(err) {
reject(err)
}
const {value, done} = res
if(done) {
resolve(value)
} else {
Promise.resolve(value).then(v => go(v), r => reject(r))
}
}
go()
})
}
const gen3 = AsyncFunction(genFn)
console.info(gen3) // 因为是异步调用,这里稍等2秒才能看到最终结果。Promise{PromiseState: 'fulfilled', PromiseResult: 100}