什么……发电机!
想了解发电机吗?
首先,你需要检查迭代器。
这是不能省略的步骤,因为生成器是通过迭代器工作的。我们可以说,生成器提供了一种更简单的自定义迭代器编写方式。
这是一个生成器:
function* breeds(){
yield "labrador";
return "chow-chow";
}
const iterator = breeds();
console.log(iterator.next())
//->{value: "labrador", done: false}
console.log(iterator.next())
//->{value: "chow-chow", done: true}
console.log(iterator.next())
//->{value: undefined, done: true}
让我们看看这里发生了什么。
首先,我们需要创建一个生成器函数,我们可以通过在函数名和函数名之间使用星号 (*)来实现。 无论函数名是什么, 这样做都有效!function* breeds()function *breeds()const breeds = function *()const breeds = function*()
(但是,在函数后面使用*是一种标准做法……所以请尽量始终使用这种语法。)function*
那个函数内部我们使用了yield ……那是什么?
yield是用来监听next()调用的。
每次我们在迭代器上使用`.next()`时,生成器都会使用下一个尚未使用的yield。这与迭代器的基本原理
相同,我们正在使用`done`键来检查迭代器的返回值!
如果其值为false,则.next()将在前一个 yield 之后调用yield 。
console.log(iterator.next())
//->{value: "labrador", done: false}
console.log(iterator.next())
//->{value: "chow-chow", done: true}
console.log(iterator.next())
//->{value: undefined, done: true}
done :true何时发生?当生成器
没有更多内容可供输出时。
但我们需要对此进行更精确的描述。
我们都知道,在 JavaScript 中,函数总是会返回一个值。
如果你没有定义返回值,JavaScript 会自动返回 undefined。
function* breeds(){
yield "labrador";
yield "chow-chow";
}
const iterator = breeds();
console.log(iterator.next())
//->{value: "labrador", done: false}
console.log(iterator.next())
//->{value: "chow-chow", done: false}
console.log(iterator.next())
//->{value: undefined, done: true}
通过移除函数的返回值,调用`.next()`将强制 JavaScript 返回一个值。{value: undefined, done: true}
所以,JS 仍然会返回 It,即使是使用生成器也是如此,因为我们仍然在讨论函数!
如果你想强制返回,你可以对迭代器使用.return()方法并结束生成器。
function* breeds(){
yield "labrador";
yield "chow-chow";
}
const iterator = breeds();
console.log(iterator.return("we <3 dogs"))
//->{value: "we <3 dogs", done: true}
console.log(iterator.next())
//->{value: undefined, done: true}
console.log(iterator.next())
//->{value: undefined, done: true}
如您所见,我们立即使用.return()方法返回并结束了生成器!
发电机并非魔法!
我们实际上并没有通过调用生成器来执行任何操作……事实上,每次使用.next()方法调用生成器时,我们都在使用迭代器接口。
我们可以将`.next()`看作是启动(调用 `yield`)和暂停(检查 ` done: ` 值)生成器函数的远程控制器。
因此,我们需要定义:
const iterator = breeds();
并打电话给iterator.next()
(迭代器,这里指的是变量名,而不是迭代器对象本身)
很多事情都可以做。
在实际工作中,我们可以用发电机做很多事情。
我们可以使用生成器为变量赋值。
我们可以获取、展开并使用for...of循环。
目前我们使用生成器一次只调用一个yield,可以说,我们是以同步的方式使用它。
但是,生成器也可以用于异步方式。
我现在不打算详细介绍……你可以查阅Promise或async/await 的相关资料,也许我们以后会讨论这个问题。Promise
异步