理解 JavaScript 中的生成器 - JavaScript 周刊

2025-06-08

理解 JavaScript 中的生成器 - JavaScript 周刊

如需定期更新,请订阅每周新闻通讯《每周更新》

在本系列文章中,我们将了解 JavaScript 中的生成器及其用例。理解 JavaScript 中的生成器 - JavaScript 周刊

什么是生成器?

首先,让我们尝试用一个简单的类比来理解这个概念。

例如,假设您正在笔记本电脑上看电影。突然有人按门铃,那是您订购的披萨。您会暂停电影并去拿披萨,然后回来从您离开的地方继续观看。对吗?

类似地, JavaScript 中的生成器也采用相同的概念。

生成器是 JavaScript 中的特殊函数,可以暂停并从中断处恢复。

此外,我们都知道,一旦正常的 javascript 函数执行完毕,就不可能中断并执行某些工作并从中断的地方返回。

例如,看看下面的代码

setTimeout(function(){
  console.log("Hello World");
},1);

function foo() {
  // NOTE: don't ever do crazy long-running loops like this
  for (var i=0; i<=700; i++) {
      console.log(i);
  }
}

foo();

但是setTimeout函数只会在循环结束后执行,无法中断for循环并执行该函数。

这就是Generators函数解决的 问题

实现生成器

 要将一个函数定义为 Generator 函数,我们需要在其后添加星号 (*)。例如:

function* getData() {
   //yield comes here.
}

每当 Generator 函数遇到 yield 语句时,它就会执行该语句,然后恢复该函数。

让我们通过一个例子来理解这个概念,

function* getData() {
  
  for(let i=0;i < 10;i++){
    console.log(yield getUser(i));
  }

}

function getUser(value) {
    return {
      id : value,
      name : "John",
      age : 20 
    }
}

const get = getData();

console.log(get.next().value)
console.log(get.next().value)
console.log(get.next().value)

在这里,我们定义一个生成器函数来获取用户数据。每次 getData() 函数遇到带有 getUser() 函数的 yield 语句时,它都会执行该函数并将数据返回给主函数。

我们需要调用next()来迭代并从生成器函数中获取值。它被称为Generator Iterator s。

什么是生成器迭代器?

生成器迭代器是一种特殊的设计模式。我们可以逐步循环遍历有序集合。

例如,考虑一个包含值的数组

['a','b','c','d','e']

使用迭代器,我们可以使用关键字next()一次循环遍历一个值。这样做的目的是,如果我们有一些函数在返回每个值后运行。我们可以用这种方式执行。

function *doIt() {
    yield 1;
    yield 2;
    yield 3;
    yield 4;
    yield 5;
}

要遍历生成器函数doIt()的值,我们需要构造一个迭代器。我们可以通过定义来实现,

var it = doIt();

同时,为了迭代生成器函数,我们需要使用关键字next()来获取值。

console.log( it.next() ); // { value:1, done:false }
console.log( it.next() ); // { value:2, done:false }

我们得到了值和一些称为done 的东西,它指示迭代器是否到达了函数的末尾。

我们也可以在生成器函数中使用return代替yield 。但是,使用return的问题在于,在 for..of 循环中,return 语句会被丢弃,不会被执行。

使用 for..of 循环

function *doIt() {
    yield 1;
    yield 2;
    yield 3;
    yield 4;
    yield 5;
    return 6;
}

for (var v of doIt()) {
    console.log( v );
}
// 1 2 3 4 5

console.log( v ); // still `5`, not `6` :(

我们在哪里使用生成器函数?

Redux-saga

最重要的是,redux saga 用于处理redux的副作用。如果你曾经使用过react/redux,你可能知道维护redux中的action creators和reducers有多难。

Redux-saga 通过将 action-creator 和 reducer 分组(称为sagas)来简化维护过程

Redux saga 明确使用 Generators 函数来实现 saga 效果,例如

  • 调用 API 并从后端获取数据
  • 从 redux 状态中选择值
  • 采取每项行动并执行一些业务逻辑并分派一些其他行动。

承诺替代方案

最重要的是,它还可以用作 promise、async/await 的替代品。

由于大多数开发人员都使用承诺,因此他们不会过多地使用生成器。

但是我们可以用Generator来解决Promise,Async/Await解决的问题。

结论

好的,这就是生成器的基础知识。

同样,我们将在即将推出的 JavaScript 周刊系列中看到更多关于 JavaScript 核心概念的内容。在此之前,您可以阅读我的其他博客文章,它们讲解了 Web 开发的基础知识。

祝您编码愉快:-)

同时,要了解有关 Javascript 的更多信息

你不知道 JS

鏂囩珷鏉ユ簮锛�https://dev.to/ganeshmani/understanding-generators-in-javascript-javascript-weekly-4p09
PREV
什么是 gRPC?如何在 Node.js 中实现 gRPC
NEXT
在 Node.js 应用程序中实现 Redis Pub/Sub