JavaScript

JavaScript 知识量:26 - 101 - 483

6.2 生成器><

生成器基础- 6.2.1 -

JavaScript中的生成器是一种特殊类型的函数,它允许在函数执行过程中暂停和恢复执行,从而可以实现在函数调用之间保持状态。生成器函数使用function*关键字来声明。

生成器函数的特点是可以返回多个值,而不是像普通函数那样只能返回一个值。每次调用生成器函数的next()方法时,它会返回一个对象,该对象包含当前迭代到的值和一个布尔值done,表示是否还有更多的值可以生成。

以下是一个简单的生成器函数示例:

function* countUpTo(n) {  
  let count = 1;  
  while (count <= n) {  
    yield count++;  
  }  
}  
  
const generator = countUpTo(5);  
  
console.log(generator.next().value); // 输出 1  
console.log(generator.next().value); // 输出 2  
console.log(generator.next().value); // 输出 3  
console.log(generator.next().value); // 输出 4  
console.log(generator.next().value); // 输出 5  
console.log(generator.next().done);  // 输出 true,表示没有更多的值可以生成

在这个示例中,定义了一个生成器函数countUpTo,它接受一个参数n,并使用yield关键字返回从1到n的整数序列。创建了一个生成器对象generator,并通过多次调用其next()方法来获取生成的值。

生成器在JavaScript中有很多用途,比如用于创建迭代器、实现异步操作等。

通过yield中断执行- 6.2.2 -

JavaScript中的生成器函数可以通过yield关键字来中断函数的执行。当生成器函数遇到yield关键字时,它会暂停执行并返回当前的值。然后,在下一次调用生成器的next()方法时,函数将从yield关键字后的位置继续执行,直到遇到下一个yield或函数结束。

这种中断执行的机制使得生成器函数可以在需要时暂停和恢复执行,从而可以在函数调用之间保持状态。

以下是一个示例,演示了使用yield关键字中断生成器函数的执行:

function* generator() {  
  console.log('Start');  
  yield 'value1';  
  console.log('After yield 1');  
  yield 'value2';  
  console.log('After yield 2');  
  yield 'value3';  
  console.log('End');  
}  
  
const gen = generator();  
console.log(gen.next().value); // 输出 'value1'  
console.log(gen.next().value); // 输出 'value2'  
console.log(gen.next().value); // 输出 'value3'

在这个示例中,定义了一个生成器函数generator,其中包含三个yield语句。当生成器函数执行到yield语句时,它会暂停执行并返回当前的值。然后,在下一次调用next()方法时,函数将从yield语句后的位置继续执行。

生成器作为默认迭代器- 6.2.3 -

可以将生成器函数用作对象的默认迭代器。要实现这一点,需要将生成器函数分配给对象的[Symbol.iterator]属性。这样,当对象需要被迭代时,JavaScript会自动调用该生成器函数来获取迭代器。

以下是一个示例,演示了如何使用生成器函数作为默认迭代器:

function* countUpTo(n) {  
  let count = 1;  
  while (count <= n) {  
    yield count++;  
  }  
}  
  
const obj = {  
  start: 1,  
  end: 5,  
  [Symbol.iterator]() {  
    return countUpTo(this.end);  
  }  
};  
  
for (const value of obj) {  
  console.log(value); // 输出 1, 2, 3, 4, 5  
}

在这个示例中,定义了一个生成器函数countUpTo,它接受一个参数n,并使用yield关键字返回从1到n的整数序列。然后,创建了一个对象obj,并将生成器函数分配给对象的[Symbol.iterator]属性。这样,当使用for...of循环遍历对象obj时,JavaScript会自动调用生成器函数来获取迭代器,并使用返回的迭代器来遍历对象的值。

提前终止生成器- 6.2.4 -

可以通过在生成器函数的return语句中指定一个值来提前终止生成器的执行。当return语句被执行时,生成器函数会立即终止,并返回指定的值。

以下是一个示例,演示了如何提前终止生成器函数的执行:

function* generator() {  
  yield 'value1';  
  yield 'value2';  
  return 'terminated';  
  yield 'value3'; // 这行代码不会被执行  
}  
  
const gen = generator();  
console.log(gen.next().value); // 输出 'value1'  
console.log(gen.next().value); // 输出 'value2'  
console.log(gen.next().value); // 输出 'terminated',同时生成器被终止  
console.log(gen.next().done);  // 输出 true,表示生成器已经终止

在这个示例中,定义了一个生成器函数generator,其中包含两个yield语句和一个return语句。当return语句被执行时,生成器函数会立即终止,并返回指定的值。在这个例子中,在第二次调用next()方法后终止了生成器的执行,因此第三次调用next()方法时,生成器已经终止,返回的对象中的done属性为true。