详解Javascript中的Generator生成器


本文摘自PHP中文网,作者青灯夜游,侵删。

什么是Generator生成器?

生成器是在函数内部运行的一些代码

  • 返回值后,它会自行暂停,并且――

  • 调用程序可以要求取消暂停并返回另一个值

这种“返回”不是传统的从函数 return。所以它被赋予了一个特殊的名称――yield

生成器语法因语言而异。 Javascript 的生成器语法类似于 PHP,但是区别也很大,如果你希望它们的作用相同,那么最终你会感到非常困惑。

在 javascript 中,如果想要使用生成器,则需要:

  • 定义特殊的生成器函数

  • 调用该函数创建一个生成器对象

  • 在循环中使用该生成器对象,或直接调用其 next 方法

我们以下面这个简单的程序做为起点,并执行以下每个步骤:

1

2

3

4

5

6

7

8

9

10

11

// File: sample-program.js

function *createGenerator() {

  for(let i=0;i<20;i++) {

    yield i

  }

}

 

const generator = createGenerator()

 

console.log(generator.next())

console.log(generator.next())

如果运行这段代码,则会得到以下输出:

1

2

3

4

$ node sample-program.js

 

{ value: 0, done: false }

{ value: 1, done: false }

下面我来解释该程序是如何工作的。

生成器函数

首先,代码中存在生成器函数的定义:

1

2

3

4

5

function* createGenerator() {

  for(let i=0;i<20;i++) {

    yield i

  }

}

function 后面的 * 告诉 javascript 这是一个生成器函数。以下写法都是生成器函数的有效定义。

1

2

3

function*createGenerator

function* createGenerator

function *createGenerator

*不是函数名的一部分。而是 function* 符号定义了生成器。

调用生成器函数

定义了生成器函数后,我们将其命名为其他名称的函数。

1

2

3

// 注意:当调用时,没有 *。 * 不是函数名称的一部分

// `function *` 是用于定义生成器函数的符号

const generator = createGenerator()

但是要记住:createGenerator 函数没有返回值。这是因为生成器函数没有传统的返回值。相反,当你直接调用生成器函数时,它总是返回实例化的 Generator 对象。

这个生成器对象具有一个 next 方法。调用 next 将在生成器函数内部运行代码。

1

2

3

4

5

function* createGenerator() {

    for(let i=0;i<20;i++) {

        yield i

    }

}

这很重要,足以再次调用它。直接调用生成器函数不会在生成器函数中运行任何代码。而是创建一个生成器对象。它在生成器对象上调用 next,从而调用生成器函数中的代码。

首次在生成器对象上调用 next 时,内部代码将会一直运行,直到出现 yield 语句。一旦执行到 yield,javascript 将会暂停该代码的执行,而 next 将返回(即给你,或yield)一个对象,该对象包含 yield 行中的值。

当你第二次(或第三次、第四次甚至更多次)再调用 next 时,代码将会取消暂停并继续运行(在上次调用时中断的地方)。变量(例如本例中的 i )将会保持它的值。当代码到达另一个 yield 语句时,该函数会再次暂停,并返回一个包含 yield 值的对象。

这就是为什么我们要调用两次 next

1

2

console.log(generator.next())

console.log(generator.next())

会得到以下输出:

1

2

{ value: 0, done: false }

{ value: 1, done: false }

生成器函数中的代码执行完毕后,将来对 next 的任何调用都会返回一个对象,该对象的值为 undefineddone 设置为 true

1

{ value: undefined, done: true }

生成器和循环

虽然可以在生成器对象上手动调用 next,但我们主要是要在循环中使用。看一下这个稍作修改的程序。

1

2

3

4

5

6

7

8

9

10

11

12

// File: sample-program.js

@highlightsyntax@jscript

function *createGenerator() {

  for(let i=0;i<5;i++) {

    yield i

  }

}

 

const generator = createGenerator()

for(const value of generator) {

  console.log(value)

}

当在 for...of 循环中使用生成器对象时,每次循环都会在生成器对象上调用 next,并用产生的值填充变量(上面的 value)。运行该程序将会输出以下内容:

1

2

3

4

5

6

$ node sample-program.js

0

1

2

3

4

在下一篇文章中,我们将更深入地探讨 for ... of 循环,并探索怎样为 javascript 提供一种内置方法来循环 javascript 中的任何对象

英文原文地址:https://alanstorm.com/javascript-generators/

作者:Alan Storm

译文地址:https://segmentfault.com/a/1190000023924834

更多编程相关知识,请访问:编程入门!!

以上就是详解Javascript中的Generator生成器的详细内容,更多文章请关注木庄网络博客

相关阅读 >>

编写javascript程序的唯一工具是纯文本编辑器吗?

一文搞懂javascript中 ! 和 !! 的区别!

手把手带你了解javascript中变量和词法环境

vue和js区别是什么

javascript怎么清除标签的浮动

javascript怎么替换所有字符串

javascript如何实现删除提示信息

详解js中的json和jsonp

javascript怎么修改div内容

javascript失去焦点如何设置

更多相关阅读请进入《javascript》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...