async / await 使用
async
函数返回一个 Promise 对象,async
函数内部return
语句返回的值,会成为then
方法回调函数的参数。
只有async
函数内部的异步操作执行完,才会执行then
方法指定的回调函数。
await
后面跟的是一个 Promise
对象,如果不是,则会包裹一层 Promise.resolve()
async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里,简而言之,就是 Generator 函数的语法糖。
Generator函数是什么?
- function关键字与函数名之间有一个星号;
- 函数体内部使用yield表达式,定义不同的内部状态
Generator 函数返回的遍历器对象,只有调用next
方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。
yield
表达式就是暂停标志。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
function* generator() { yield 1; yield 2; yield 3; return 4; } const self = generator(); console.log(self.next()); console.log(self.next()); console.log(self.next()); console.log(self.next());
function* generator() { yield Promise.resolve("1"); yield Promise.resolve("2"); yield Promise.resolve("3"); return Promise.resolve("4"); } const self = generator(); const next1 = self.next(); next1.value.then((res1) => { console.log(res1); const next2 = self.next(); next2.value.then((res2) => { console.log(res2); }); });
|
async / await 实现原理
- 封装一个函数, 接收一个生成器函数作为参数, 该函数返回一个 Promise 对象
- 首先调用生成器函数, 获取生成器对象
- 我们需要自动执行生成器函数的每一步, 我们再封装一个 step 函数, 传入一个匿名函数作为参数, 并执行生成器函数, 用来获取生成器函数中下一个 yield 表达式的值, 直到 next.done 为 true 或者 抛出了错误.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| async function fn(args) { }
function fn(args) { return spawn(function* () {}); }
function spawn(genFn) { return new Promise((resolve, reject) => { const gen = genFn(); function step(nextFn) { let next; try { next = nextFn(); } catch (e) { return reject(e); } if (next.done) { return resolve(next.value); } Promise.resolve(next.value).then( function (v) { step(function () { return gen.next(v); }); }, function (e) { step(function () { return gen.throw(e); }); } ); } step(function () { return gen.next(undefined); }); }); }
|
参考文章
- https://juejin.cn/post/7318083950856241162?searchId=20240407181153A8E8CE8B4E109415D8C7#heading-5