Javascript生成器(Generator)的介绍与使用
什么是生成器?
生成器是在函数内部运行的一些代码
- 返回值后,它会自行暂停,并且——
- 调用程序可以要求取消暂停并返回另一个值
这种“返回”不是传统的从函数return。所以它被赋予了一个特殊的名称——yield。
生成器语法因语言而异。Javascript的生成器语法类似于PHP,但是区别也很大,如果你希望它们的作用相同,那么最终你会感到非常困惑。
在javascript中,如果想要使用生成器,则需要:
- 定义特殊的生成器函数
- 调用该函数创建一个生成器对象
- 在循环中使用该生成器对象,或直接调用其next方法
我们以下面这个简单的程序做为起点,并执行以下每个步骤:
//File:sample-program.js function*createGenerator(){ for(leti=0;i<20;i++){ yieldi } } constgenerator=createGenerator() console.log(generator.next()) console.log(generator.next())
如果运行这段代码,则会得到以下输出:
$nodesample-program.js
{value:0,done:false}
{value:1,done:false}
下面我来解释该程序是如何工作的。
生成器函数
首先,代码中存在生成器函数的定义:
function*createGenerator(){ for(leti=0;i<20;i++){ yieldi } }
function后面的*告诉javascript这是一个生成器函数。以下写法都是生成器函数的有效定义。
function*createGenerator function*createGenerator function*createGenerator
* 并不是函数名的一部分。而是function*符号定义了生成器。
调用生成器函数
定义了生成器函数后,我们将其命名为其他名称的函数。
//注意:当调用时,没有*。*不是函数名称的一部分 //`function*`是用于定义生成器函数的符号 constgenerator=createGenerator()
但是要记住:createGenerator函数没有返回值。这是因为生成器函数没有传统的返回值。相反,当你直接调用生成器函数时,它总是返回实例化的Generator对象。
这个生成器对象具有一个next方法。调用next将在生成器函数内部运行代码。
function*createGenerator(){ for(leti=0;i<20;i++){ yieldi } }
这很重要,足以再次调用它。直接调用生成器函数不会在生成器函数中运行任何代码。而是创建一个生成器对象。它在生成器对象上调用next,从而调用生成器函数中的代码。
首次在生成器对象上调用next时,内部代码将会一直运行,直到出现yield语句。一旦执行到yield,javascript将会暂停该代码的执行,而next将返回(即给你,或yield)一个对象,该对象包含yield行中的值。
当你第二次(或第三次、第四次甚至更多次)再调用next时,代码将会取消暂停并继续运行(在上次调用时中断的地方)。变量(例如本例中的i)将会保持它的值。当代码到达另一个yield语句时,该函数会再次暂停,并返回一个包含yield值的对象。
这就是为什么我们要调用两次 next
console.log(generator.next()) console.log(generator.next())
会得到以下输出:
{value:0,done:false}
{value:1,done:false}
生成器函数中的代码执行完毕后,将来对next的任何调用都会返回一个对象,该对象的值为undefined且done设置为true。
{value:undefined,done:true}
生成器和循环
虽然可以在生成器对象上手动调用next,但我们主要是要在循环中使用。看一下这个稍作修改的程序。
//File:sample-program.js @highlightsyntax@jscript function*createGenerator(){ for(leti=0;i<5;i++){ yieldi } } constgenerator=createGenerator() for(constvalueofgenerator){ console.log(value) }
当在for...of循环中使用生成器对象时,每次循环都会在生成器对象上调用next,并用产生的值填充变量(上面的value)。运行该程序将会输出以下内容:
$nodesample-program.js
0
1
2
3
4
在下一篇文章中,我们将更深入地探讨for...of循环,并探索怎样为javascript提供一种内置方法来循环javascript中的任何对象。
总结
到此这篇关于Javascript生成器(Generator)的文章就介绍到这了,更多相关Javascript生成器(Generator)内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!