前言
现在ECMAScript6 异步编程,我们都喜欢用 async/await 这种解决方案来处理,写起来代码看起来也很爽。但底层实现原理却比较少人了解,然后最近面试也经常被问到,写篇文章记录下。
async/await 是什么?
我们之前的异步编程方案有回调函数、Promise对象、Generator函数,再到现在E7的async/await。我们通过它的实现原理可以了解到 async/await其实是 Generator 函数的语法糖,可以理解为 async/await = Generator 函数 + 自动执行器。
async/await的实现原理
// Generator 函数 + 自动执行器
function spawn (genF) {
return new Promise(function(resolve, reject) {
var gen = genF()
function step (nextF) {
var next
try {
next = nextF()
} catch (error) {
return reject(error)
}
if (next.done) return resolve(next.value)
Promise.resolve(next.value).then(
function(value) {
step(function() {
return gen.next(value)
})
},
function(error) {
step(function() {
return gen.throw(error)
})
})
}
step(function() {
return gen.next()
})
})
}
Generator函数实现async/await使用案例
// 异步函数例子
function wait(time) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(`wait time: ${time}`)
}, time)
})
}
/* generator test start */
function * genF(time = 1000) {
let res = yield wait(time)
console.log(res)
}
function asyncByGen() {
if(typeof arguments[0] !== 'function') throw('first argument must be a function')
var fn = arguments[0]
var args = Array.prototype.slice.call(arguments, 1)
return spawn(fn.bind(null, args))
}
// use
asyncByGen(genF, 1200) // wait time: 1200
/* generator test end */
/* async test start */
async function asyncF(time = 1000) {
let res = await wait(time)
console.log(res)
}
// use
asyncF(1200) // wait time: 1200
/* async test end */
最后
本文是通过学习阮大神的异步编程系列文章,然后code实现一遍,比之前单纯看文章不code真的要收获更多。每天进步一点点~