发布于 2026-01-06 3 阅读
0

JavaScript 中使用生成器函数的 4 种方法 | 示例 | 优势 感谢阅读,我是 Tharun Shiv,也就是开发者 Tharun。

JavaScript 中使用生成器函数的 4 种方法 | 示例 | 优势

感谢阅读,我是 Tharun Shiv,又名开发者 Tharun。

本文内容(点击跳转至相应主题):

YouTube 完整视频 - 我的频道 - Developer Tharun

什么是生成函数?

有没有想过如果一个函数需要处理无限多个输入或输出会发生什么?这正是生成器函数可以处理的情况。

生成器函数返回一个迭代器,我们可以利用这个迭代器在函数执行过程中暂停,执行一些操作,然后在任何时候恢复执行。普通函数会在执行完毕后返回,但生成器函数可以被暂停任意次数,并在之后恢复执行。

Want to learn Modern JavaScript ES6 - 2020??
Scroll to the end of the post
Enter fullscreen mode Exit fullscreen mode

回顾:什么是函数?

函数是一段代码块,可以调用任意次数来完成特定功能,有时还会返回结果。

它是如何运作的?

  1. 调用生成器函数并不会立即完全执行该函数。它会返回一个迭代器对象,该对象可用于执行该函数。
  2. 因此,该函数可以分部分执行,具体执行哪些部分由表达式决定yield。(代码解释如下,不用担心)。
  3. 为了执行这些部分,.next()需要对迭代器使用该方法。.next()调用该方法后,函数会继续执行,直到yield找到下一个迭代器、函数执行完毕或return执行完某个语句为止。
  4. 每次执行该.next()方法时,生成器函数都会返回一个如下所示的对象。


{
   value: 'some-value',
   done: false
}


Enter fullscreen mode Exit fullscreen mode

这里value是发送的值yield,它done指示生成器函数是否已完全运行。

示例

1. 生成器函数的基本用法

生成器函数使用星号定义,*星号可以紧跟在函数关键字之后,也可以紧跟在函数名之前。以下示例生成无限多个自然数,可在需要时使用。



    function* naturalNumbers() {
        let number=1;
        while (true)
            yield number++;
    }

    var naturalNumberIterator = naturalNumbers();

    console.log(naturalNumberIterator.next().value);
    console.log(naturalNumberIterator.next().value);
    console.log(naturalNumberIterator.next().value);
    console.log(naturalNumberIterator.next().value);


Enter fullscreen mode Exit fullscreen mode

上述代码的输出结果如下:

1
2
3
4
Enter fullscreen mode Exit fullscreen mode

2. 在生成器内部调用生成器(哇哦……盗梦空间)

我们可以使用 `require` 函数yield*从一个生成器内部调用另一个生成器。(是不是很神奇?)



    function *anotherGenerator(name) {
        yield `From Another Generator, ${name}`
    }

    function *myGenerator(name) {
        yield `Hi ${name}`;
        yield* anotherGenerator(name)
        yield 'Bye!'
    }

    let gen = myGenerator('shiv')
    console.log(gen.next().value);
    console.log(gen.next().value);
    console.log(gen.next().value);


Enter fullscreen mode Exit fullscreen mode

上述代码的输出结果如下:

Hi shiv
From Another Generator, shiv
Bye!
Enter fullscreen mode Exit fullscreen mode

3. 向生成器传递参数

想知道生成器还能做什么吗?如果我告诉你,你可以向生成器传递参数呢?同样,只需将参数传递给生成器,.next()然后在生成器函数内部的关键字中使用它即可yield。下面是一个演示示例。



    function *myGenerator() {
        console.log('Hey ', yield)
        console.log('Are you ',yield)
    }

    let gen = myGenerator()

    gen.next()
    gen.next('tharun')
    gen.next('shiv')


Enter fullscreen mode Exit fullscreen mode

请注意,您必须.next()在程序开始时调用一次该方法,这将执行函数直到遇到 yield 关键字为止。接下来,该方法.next('tharun')会将值传递'tharun'给生成器,并替换 yield 的位置。以下是程序的输出结果。

Hey tharun
Are you shiv
Enter fullscreen mode Exit fullscreen mode

4. 一旦归还,不再产生收益

想知道在生成器函数内部执行return语句会发生什么吗?下面的例子就演示了这一点。它会从生成器函数返回,但不会提供对yield以下任何内容的访问权限。



    function* yieldAndReturn() {
    yield "Y";
    return "R";
    yield "unreachable";
    }

    var gen = yieldAndReturn()
    console.log(gen.next());
    console.log(gen.next());
    console.log(gen.next());


Enter fullscreen mode Exit fullscreen mode

输出结果如下所示。您无法选择yield“不可达”。

{"value":"Y","done":false}
{"value":"R","done":true}
{"done":true}
Enter fullscreen mode Exit fullscreen mode

使用生成器的优势是什么?为什么要使用它们?

1. 惰性求值 - 仅在需要时运行

假设存在无限的数据流,我们不可能花费所有时间来评估这些数据。因此,我们可以使用生成器函数,在需要时进行评估。

2. 内存效率高

由于采用了惰性求值方法,因此只使用必要的数据和计算。

我该去哪里学习这些?

我找到了一个可以学习这些内容、提出疑问并获得结业证书的平台。请查看 Udemy 上的这门课程(点击):JavaScript Modern ES6 - 2020 - The Complete Course - Udemy。我的 YouTube 频道上前几个视频是免费的。点击这里观看:Being a Pro - YouTube JavaScript Playlist。感谢阅读!

本文最初发表于https://tharunshiv.com

作者:

感谢阅读,我是 Tharun Shiv,又名开发者 Tharun。

塔伦·希夫

文章来源:https://dev.to/developertharun/4-ways-to-use-generator-functions-in-javascript-examples-advantages-2ohd