Generator + Promise实现async+await的效果

很久以前用koajs 1的时候也看过co库的核心源码,后来不用了,前段时间又涉及到了相关的问题,特地重新学习一下, koajs 1 中如何实现的async await的效果。

首先,2个基本知识:

  1. Promise.resolve flattens nested layers of promise-like objects (e.g. a promise that resolves to a promise that resolves to something) into a single layer.
  2. gen.next(value) The value to send to the generator. The value will be assigned as a result of a yield expression. i.e in [variable] = yield [expression], the value passed to the .next function will be assigned to [variable]

既然是程序员,还是直接分析代码吧。

function doTask1() {
  return new Promise((resolve) =>
    setTimeout(
      () => resolve(1111),
      1111
    )
  )
}

function doTask2() {
  return new Promise((resolve) =>
    setTimeout(
      () => resolve(2222),
      1111
    )
  )
}

function runner(gen) {
  const g = gen();
  function run(arg) {
    console.log('arg', arg);
    let result = g.next(arg); // 2
    if (result.done) {
      console.log('done', result);
      // return result.value; done的时候
    } else {
      console.log('result.value', result.value);
      return Promise.resolve(result.value).then(run); //4
    }
  }
  run();  // 1
}

runner(function* () {
  const result1 = yield doTask1(); //3
  console.log(result1);
  const result2 = yield doTask2(); //5
  console.log(result2);
});

程序真正的起始点是1处,2处调用next方法就会执行到3处的yield,此时2处的result就是一个这样的对象:

{ value: Promise { <pending> }, done: false }

其value是一个处于pending状态的promise,这个promise将来会发射出1111。之后程序执行到4处,根据知识点1,4处的then接收到的值会是1111,之后会进行这样的调用:run(1111)。
程序又执行到2处,根据知识点2,next方法传值1111给3处的result1。。。,这次的next会执行到5处的yield,这个yield会返回这样的一个对象:

{ value: Promise { <pending> }, done: false }

这个对象又会赋值给2处的result,之后又执行到4处,后面的同理不说了

注:
在写此篇博客的时候,身边有一位远在千里之外的小可爱陪伴,让我想起一首词,放在这里送给她吧:

少年游

张耒

含羞倚醉不成歌,纤手掩香罗。
偎花映烛,偷传深意,酒思入横波。

看朱成碧心迷乱,翻脉脉、敛双蛾。
相见时稀隔别多,又春尽、奈愁何。

参考文献:
https://hackernoon.com/async-await-generators-promises-51f1a6ceede2

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值