解释 JavaScript 中不同类型的生成器


众所周知,JavaScript 是一种轻量级的编程语言,其中生成器是在 ECMAScript 2015 中引入的。生成器是一个具有多个输出值的流程,可以停止和启动。在 JavaScript 中,生成器由生成器函数组成,该函数生成可迭代的生成器对象。

在本文中,我们将讨论 JavaScript 中的生成器,以及 JavaScript 中不同类型的生成器,并详细介绍其语法和示例。

JavaScript 生成器简介

生成器函数与普通函数相同,但有一点区别,即生成器函数可以恢复和暂停。在 JavaScript 中,通常情况下,函数一旦被调用就不会停止。通常,生成器的概念在异步编程中可见。

JavaScript 生成器函数语法

现在我们将讨论 JavaScript 中生成器函数的语法,并将其与普通函数进行比较。

函数 * 语法用于构建生成器函数,yield 关键字用于暂停它们。

function * genFunc() {
   yield 'Hello';
   yield 'World';
}
const g = genFunc(); // g is a generator
g.next(); // { value: 'Hello', done: false }
g.next(); // { value: 'World', done: false }
g.next(); // { value: undefined, done: true }
…

第一次调用生成器函数时,不会运行其任何代码,而是返回一个生成器对象。通过调用生成器的 next() 方法来使用值,该方法运行代码,直到遇到 yield 关键字,此时它会暂停并等待再次调用 next()。

在上面的代码中,在我们的最终语句之后,持续调用 g.next() 只会产生相同的返回值对象:{value: undefined, done: true},因为我们没有在 genFunc() 函数中的“world”之后定义任何内容。

yield 关键字会暂停生成器函数的执行,并将跟随它的表达式的值提供给生成器的调用方。它类似于 return 关键字的基于生成器的版本。它只能直接从包含 yield 的生成器函数中调用。

与普通函数的比较

function regFunc() {
   console.log("Hello World");
}
// Hello World

在普通函数中,我们不使用“*”函数,如您在上面的示例中看到的,它也不使用 yield 函数。正如我们上面讨论的那样,普通函数和生成器函数之间的主要区别在于生成器函数可以停止和暂停。因此,通过上面的示例,您可以看到我们没有选择停止它并直接一起打印整个语句,即“Hello world”。

我们已经了解了生成器函数的基本知识,现在让我们转向不同类型的生成器函数 -

普通生成器

在普通生成器中,生成器充当迭代器,在每次执行 next() 方法调用以生成函数后生成下一个值。让我们看一个示例,我们将逐个产生数字,直到列表结束。

function* generator_function(){
   for(var cur = 0 ; cur<7; cur++){
      yield cur;
   }
}
var object_generator = generator_function();
console.log(object_generator.next().value);
console.log(object_generator.next().value);
console.log(object_generator.next().value);
console.log(object_generator.next().value);
console.log(object_generator.next().value);
console.log(object_generator.next().value);
console.log(object_generator.next().value);

在上面的代码中,我们创建了一个带有 yield 关键字的普通生成器函数,并使用 next() 函数多次调用它。

带参数的生成器

带参数的生成器与普通生成器略有不同,这次我们必须将参数与 next() 函数一起传递,以将其发送到生成器函数。此外,每次我们传递参数时,它都会在 yield 关键字之后存储,而不是之前,我们将在接下来的示例中了解此概念 -

function* generator_function(){
   console.log("start of the function")
   temp = yield;
   console.log("This is the first value passed: " + temp)
   temp = yield;
   console.log("This is the second value passed: " + temp)
}
var object_generator = generator_function();
object_generator.next("This is not the first ");
object_generator.next("this is first");
object_generator.next("this is second");
object_generator.next();

在上面的代码中,我们定义了生成器函数,这次我们将参数传递给它。当我们第一次调用该对象时,给定的参数不会被打印,因为这是在“yield”关键字之前发送的,然后发送的值存储在变量中并打印,在第二个打印值之后不会发生任何事情,因为没有 yield。

带有对象属性的生成器

生成器可以用作对象,当我们调用它们时,它们将简单地返回值赋给它们,并且可以打印。为了理解这个概念,让我们看一个例子。

function* generator_function(){
   yield "First value"
   yield "Second value"
   yield "Third value"
}
var object_generator = generator_function();
console.log(object_generator.next().value);
console.log(object_generator.next().value);
console.log(object_generator.next().value);

在上面的代码中,首先,我们定义了三个带有字符串的 yield 表达式,当我们调用生成器时,它们后面的字符串将被返回。

还存在其他类型的生成器,例如带有返回类型的生成器,以及一些包含其他生成器的生成器等。

结论

在本文中,我们了解到生成器函数与普通函数相同,但有一点区别,即生成器函数可以恢复和暂停。在 JavaScript 中,通常情况下,函数一旦被调用就不会停止。通常,生成器的概念在异步编程中可见。有各种类型的生成器,例如普通生成器、带参数的生成器、类似对象的生成器、包含其他生成器的生成器等。

更新于: 2023年3月17日

121 次浏览

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告