JavaScript 生成器

x33g5p2x  于2022-06-06 转载在 Java  
字(4.3k)|赞(0)|评价(0)|浏览(220)

在本教程中,您将借助示例了解 JavaScript 生成器。在 JavaScript 中,生成器提供了一种使用函数和迭代器的新方法。
    使用生成器,

  • 您可以从函数内部的任何位置停止执行函数
  • 并从暂停的位置继续执行代码
创建 JavaScript 生成器

要创建生成器,您需要首先使用 function* 符号定义生成器函数。生成器函数的对象称为生成器。

// define a generator function
function* generator_function() {
   ... .. ...
}

// creating a generator
const generator_obj = generator_function();

注意:生成器函数用 * 表示。您可以使用 function* generatorFunc() {…} 或 function *generatorFunc(){…} 创建。

使用 yield 暂停执行

如上所述,您可以暂停生成器函数的执行,而不执行整个函数体。为此,我们使用 yield 关键字。例如,

// generator function
function* generatorFunc() {

    console.log("1. code before the first yield");
    yield 100;
    
   console.log("2. code before the second yield");
    yield 200;
}

// returns generator object
const generator = generatorFunc();

console.log(generator.next());

输出

1. code before the first yield
{value: 100, done: false}

这里,

  • 创建了一个名为 generator 的生成器对象。
  • 当 generator.next() 被调用时,执行到第一个 yield 的代码。遇到yield时,程序返回值并暂停生成器函数。

注意:您需要在使用之前将生成器对象分配给变量。

多个 yield 语句的工作原理

yield 表达式返回一个值。但是,与 return 语句不同,它不会终止程序。这就是为什么您可以从最后一个 yield 位置继续执行代码。例如,

function* generatorFunc() {

    console.log("1. code before first yield");
    yield 100;

   console.log("2. code before the second yield");
    yield 200;

    console.log("3. code after the second yield");
}

const generator = generatorFunc();

console.log(generator.next());
console.log(generator.next());
console.log(generator.next());

输出

1. code before first yield
{value: 100, done: false}
2. code before second yield
{value: 200, done: false}
3. code after the second yield
{value: undefined, done: true}

这是该程序的工作原理。

  • 第一个 generator.next() 语句执行代码直到第一个 yield 语句并暂停程序的执行。
  • 第二个 generator.next() 从暂停位置开始程序。
  • 当所有元素都被访问时,返回 {value: undefined, done: true}。

将参数传递给生成器函数

您还可以将参数传递给生成器函数。例如,

// generator function
function* generatorFunc() {

    // returns 'hello' at first next()
    let x = yield 'hello';
    
    // returns passed argument on the second next()
    console.log(x);
    console.log('some code');

    // returns 5 on second next()
    yield 5;
    
}

const generator = generatorFunc();

console.log(generator.next());
console.log(generator.next(6));
console.log(generator.next());

输出

{value: "hello", done: false}
6
some code
{value: 5, done: false}
{value: undefined, done: true}

在上述程序中,

  • 第一个 generator.next() 返回 yield 的值(在这种情况下,‘hello’)。但是,该值未分配给 let x = yield ‘hello’; 中的变量 x
{value: "hello", done: false}
  • 遇到 generator.next(6) 时,代码从 let x = yield ‘hello’; 开始,并将参数 6 分配给 x。此外,剩余的代码会执行到第二个 yield。
6
some code
{value: 5, done: false}
  • 当第三个 next() 被执行时,程序返回 {value: undefined, done: true}。这是因为没有其他的 yield 语句。
{value: undefined, done: true}
生成器用于实现迭代

生成器提供了一种更简单的方法来实现迭代器。
    如果要手动实现迭代器,则必须使用 next() 方法创建一个迭代器并保存状态。例如,

// creating iterable object
const iterableObj = {

    // iterator method
    [Symbol.iterator]() {
        let step = 0;
        return {
            next() {
                step++;
                if (step === 1) {
                    return { value: '1', done: false};
                 }
                else if (step === 2) {
                    return { value: '2', done: false};
                }
                else if (step === 3) {
                    return { value: '3', done: false};
                }
                return { value: '', done: true };
            }
        }
    }
}

for (const i of iterableObj) {
 console.log(i);
}

输出

1
2
3

由于生成器是可迭代的,因此您可以以更简单的方式实现迭代器。然后您可以使用 for…of 循环遍历生成器。例如,

// generator function
function* generatorFunc() {
  
    yield 1;
    yield 2;
    yield 3;
}

const obj = generatorFunc();

// iteration through generator
for (let value of obj) {
    console.log(value);
}
生成器方法
方法描述
next()返回 yield 值
return()返回一个值并终止生成器
throw()抛出错误并终止生成器
JavaScript return 与 yield 关键字
return 关键字yield 关键字
返回值并终止函数。返回值并暂停函数但不终止函数。
可用于普通函数和生成器函数。仅在生成器函数中可用。
带 return 的 JavaScript 生成器函数

您可以在生成器函数中使用 return 语句。return 语句返回一个值并终止函数(类似于常规函数)。例如,

// generator function
function* generatorFunc() {

    yield 100;

   return 123;

   console.log("2. some code before second yield");
    yield 200;
}

// returns generator object
const generator = generatorFunc();

console.log(generator.next());
console.log(generator.next());
console.log(generator.next());

输出

{value: 100, done: false}
{value: 123, done: true}
{value: undefined, done: true}

在上面的程序中,当遇到 return 语句时,它返回值,done 属性变为 true,函数终止。因此,return 语句之后的 next() 方法不会返回任何内容。
    注意:您也可以使用 return() 方法而不是上面代码中的 return 语句,类似 generator.return(123);

JavaScript 生成器 Throw 方法

您可以使用 throw() 方法在生成器函数上显式抛出错误。使用 throw() 方法会引发错误并终止函数。例如,

// generator function
function* generatorFunc() {
    yield 100;
    yield 200;
}

// returns generator object
const generator = generatorFunc();

console.log(generator.next());

// throws an error
// terminates the generator
console.log(generator.throw(new Error('Error occurred.')));
console.log(generator.next());

输出

{value: 1, done: false}
Error: Error occurred.
生成器的用途
  • 生成器让我们在编写异步任务时编写更简洁的代码。
  • 生成器提供了一种更简单的方法来实现迭代器。
  • 生成器仅在需要时执行其代码。
  • 生成器具有内存效率。

生成器是在 ES6 中引入的。一些浏览器可能不支持使用生成器。要了解更多信息,请访问JavaScript 生成器支持。

上一教程 :Iterators and Iterables                                          下一教程 :JS Regex

参考文档

[1] Parewa Labs Pvt. Ltd. (2022, January 1). Getting Started With JavaScript, from Parewa Labs Pvt. Ltd: https://www.programiz.com/javascript/generators

相关文章