vlambda博客
学习文章列表

3分钟看懂 JavaScript 生成器

作者 | Dylan Kerler
译者 | 王强
策划 | 李俊辰
社区中关于 JavaScript 中生成器(generator)类型的讨论很少见,这是因为我们很少碰到实际需要使用它的场景。但这并不能否定这一特性的实用性——因为当你真的遇上这类场景时,就会发现生成器真的很好用了。

就像编程领域中的大多数事物一样,生成器类型只是一种工具;具体来说,它是一种专业工具。

我们来看一个实践中生成器的示例,然后一步步分析,看看它是如何工作的:

3分钟看懂 JavaScript 生成器

上面是定义的一个生成器。你会发现它与常规函数非常相似,区别就是它有一个 * 和一个 yield 关键字。* 告诉 JavaScript 这是一个生成器函数,然后来看 yield。首先,我们看一个生成器运行示例:

3分钟看懂 JavaScript 生成器

这里的 someGenerator 返回了一个 iterator,使我们可以访问 next 方法。每次调用 next 时,函数将运行我们的代码,直到遇到 yield 语句为止。当我们遇到 yield 语句时将暂停执行,直到 next 被再次调用。当 someGenerator 完成执行后,下次我们调用 next 时将收到一个对象,该对象有一个 done 键,其值设置为 true。

很整洁是吧?其实返回的 iterator 允许我们做的事情还有很多。我们还可以访问 for…of 语句以及其他 iterator 方法,例如 spread 运算符:

3分钟看懂 JavaScript 生成器

现在,我们了解了生成器的基础使用知识,下面来看一些用例。

一个常见的用例是维护基于一个索引的 id 生成器的状态。假设我们有一个项目的映射 / 对象,还想公开一个函数,允许用户向该映射添加一个项目——每个项目都应根据插入顺序获得唯一的 ID。我们可以通过生成器来实现 ID 的生成:

3分钟看懂 JavaScript 生成器

另一个示例是将 UX 流程抽象为一个函数。假设我们有一个 UX 设计;用户单击一个按钮,然后进行一些计算,完成计算后我们要显示另一个按钮,单击该按钮会执行更多计算,然后刷新窗口。

我们可以将所有这些都放到一个函数中,但这可能会造成混乱。相比之下,由于我们知道 UX 设计流程的顺序,因此可以使用生成器解决:

这里我们成功地隔离了 UX 设计和逻辑,从而简化了测试,增强了可读性和维护性。每次完成计算时,我们都会在用户界面中显示下一个阶段。

    小结    

一般情况下,开发者不需要用到生成器,但是在某些特定场景中,当你使用生成器时会很喜欢它的——它们可以帮助你简化迭代过程,并为需要延迟计算有序值的场景提供一个整洁的解决方案。

延伸阅读

https://medium.com/swlh/understand-javascripts-generators-in-3-minutes-8af75c9c4f5f