返回

JS 生成器函数的工作原理

前端

在 JavaScript 中,生成器函数是一种特殊的函数,它可以生成一系列的值。与普通函数不同,生成器函数可以暂停执行并保存其状态,以便稍后恢复执行。这使得生成器函数非常适合用于处理无限序列或迭代数据。

生成器函数的本质

本质上,生成器函数还是一个函数,因此它的执行离不开执行上下文。在执行 gen = generator() 这句代码之前,执行上下文的栈状态如下:

  1. 全局执行上下文(顶层作用域)
  2. generator 函数的执行上下文(本地作用域)

当执行 gen() 时,会创建一个新的执行上下文,并压入执行上下文栈顶。新的执行上下文包含了 generator 函数的本地变量和参数,以及对 generator 函数的引用。

暂停执行和恢复执行

生成器函数可以通过 yield 来暂停执行并保存其状态。当执行 yield 时,生成器函数会将当前的值返回给调用者,并将执行权交回给调用者。调用者可以稍后通过再次调用生成器函数来恢复执行。

当恢复执行时,生成器函数会从上次暂停的地方继续执行。生成器函数的本地变量和参数仍然保存在执行上下文中,因此生成器函数可以继续使用这些变量和参数。

生成器函数的应用场景

生成器函数非常适合用于处理无限序列或迭代数据。例如,我们可以使用生成器函数来生成斐波那契数列:

function* fibonacci() {
  let [a, b] = [0, 1];
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

for (const n of fibonacci()) {
  if (n > 100) {
    break;
  }
  console.log(n);
}

这段代码使用生成器函数 fibonacci() 来生成斐波那契数列。fibonacci() 函数首先定义两个变量 ab,并将其初始化为 0 和 1。然后,它使用一个无限循环来生成斐波那契数列。在循环中,它首先使用 yield 关键字将 a 的值返回给调用者。然后,它将 ab 的值交换,并计算出下一个斐波那契数。

调用者可以使用 for-of 循环来遍历生成器函数返回的序列。在上面的代码中,for-of 循环将遍历 fibonacci() 函数返回的斐波那契数列,并将其打印到控制台。

结论

生成器函数是 JavaScript 中一种非常强大的工具,它可以用于处理无限序列或迭代数据。生成器函数可以通过 yield 关键字来暂停执行并保存其状态,这使得它非常适合用于处理大规模数据或需要延迟计算的情况。