利用Promise实现一个Generator函数的自执行器

1,778 阅读3分钟

这篇文章我们聊一聊Generator函数,因为它和Promise息息相关!

Generator函数的特性

最主要的两点:

  • 拥有管理状态的状态机
  • 没有自动的执行器

下面是一个常见的用法:

运行结果如下:

结合代码可以看出来,每次调用next方法都会输出当前的状态,这个状态是一个拥有value和done的对象,value代表yield后面的运行结果,done代表Generator函数所有的状态有没有运行完毕。Generator函数自己本身不会自动向下执行下面其他的状态,总会卡在一个yield处,需要手动调用next方法才会往下走!

实现一个Generator函数的自执行器

第一步:实现一个基本的autoGen函数,把Generator函数作为第一个参数传入,其他参数当做Generator函数的参数,然后返回一个promise对象,所有的逻辑都放在这个promise对象中处理。

第二步:按照惯例,我们肯定需要校验antoGen传入的各种参数,如果不是Generator函数呢,我们需要提前return,这里的校验比较简单,就是看gen运行后的对象是否具有next属性方法,其实可以多校验一些特征,比如构造函数,静态方法等!

既然要实现自动执行,那么我们最多只调用一次,这里需要实现一个开关,就像promise数据流一样!

第三步:实现一个开关fullfill方法,它首先去执行一次gen.next,这之后的事情就交给next方法去循环直到尽头。

实现next方法

第一种情况:ret是Generator函数每次运行后的状态,当ret.done===true时,预示着所有状态运行结束,我们就直接resolve,比较简单,没什么好说的。

第二种情况(非最后一次状态):ret.value是非Generator函数,我们可以直接用一个Promise对象处理

此处我们需要写一个rejected函数,至少不能把then的第二个参数控制吧。在rejected方法中,我们利用throw方法,如果gen内部抓住了异常,状态可以继续往下走,如果抓不住,那就直接整体逻辑reject。

第二种情况我们不关心Generator函数状态的值到底是什么,我们统统把它交给Promise处理,Promise处理完成之后会调用next方法继续向下走。

第三种情况:ret.value是Generator函数

这种情况下,我们直接递归,再次调用autoGen方法,它返回一个Promise对象,这个对象要和上层的Generator状态连接起来,所以后面加了一个then,让递归上来的结果通过then继续驱动上一层的next方法。

验证:

这段代码展示了三种情况

总结

我们大体上实现了一个简单的Genenrator自执行器,但是细节上还需要雕琢,当然网上有很多大牛实现的这种功能的库,大家可以对照学习,加深理解。

喜欢我的文章就关注我吧,有问题可以发表评论,我们一起学习,共同成长!(收藏和转发之前,关注一下吧,你们的关注是我的动力!)