JavaScript 中使用生成器函数的 4 种方法 | 示例 | 优势
感谢阅读,我是 Tharun Shiv,又名开发者 Tharun。
本文内容(点击跳转至相应主题):
YouTube 完整视频 - 我的频道 - Developer Tharun
什么是生成函数?
有没有想过如果一个函数需要处理无限多个输入或输出会发生什么?这正是生成器函数可以处理的情况。
生成器函数返回一个迭代器,我们可以利用这个迭代器在函数执行过程中暂停,执行一些操作,然后在任何时候恢复执行。普通函数会在执行完毕后返回,但生成器函数可以被暂停任意次数,并在之后恢复执行。
Want to learn Modern JavaScript ES6 - 2020??
Scroll to the end of the post
回顾:什么是函数?
函数是一段代码块,可以调用任意次数来完成特定功能,有时还会返回结果。
它是如何运作的?
- 调用生成器函数并不会立即完全执行该函数。它会返回一个迭代器对象,该对象可用于执行该函数。
- 因此,该函数可以分部分执行,具体执行哪些部分由表达式决定
yield。(代码解释如下,不用担心)。 - 为了执行这些部分,
.next()需要对迭代器使用该方法。.next()调用该方法后,函数会继续执行,直到yield找到下一个迭代器、函数执行完毕或return执行完某个语句为止。 - 每次执行该
.next()方法时,生成器函数都会返回一个如下所示的对象。
{
value: 'some-value',
done: false
}
这里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);
上述代码的输出结果如下:
1
2
3
4
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);
上述代码的输出结果如下:
Hi shiv
From Another Generator, shiv
Bye!
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')
请注意,您必须.next()在程序开始时调用一次该方法,这将执行函数直到遇到 yield 关键字为止。接下来,该方法.next('tharun')会将值传递'tharun'给生成器,并替换 yield 的位置。以下是程序的输出结果。
Hey tharun
Are you shiv
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());
输出结果如下所示。您无法选择yield“不可达”。
{"value":"Y","done":false}
{"value":"R","done":true}
{"done":true}
使用生成器的优势是什么?为什么要使用它们?
1. 惰性求值 - 仅在需要时运行
假设存在无限的数据流,我们不可能花费所有时间来评估这些数据。因此,我们可以使用生成器函数,在需要时进行评估。
2. 内存效率高
由于采用了惰性求值方法,因此只使用必要的数据和计算。
我该去哪里学习这些?
我找到了一个可以学习这些内容、提出疑问并获得结业证书的平台。请查看 Udemy 上的这门课程(点击):JavaScript Modern ES6 - 2020 - The Complete Course - Udemy。我的 YouTube 频道上前几个视频是免费的。点击这里观看:Being a Pro - YouTube JavaScript Playlist。感谢阅读!
本文最初发表于https://tharunshiv.com
作者:
