36.generator
# generator函数
generator函数是ES6引入的一种特殊函数,它可以产生迭代器。相较于普通函数,它具有特殊的语法和行为,主要用于实现可暂停和可恢复的函数执行。
背景:在ES6之前,JavaScript中的函数是一次性的,无法在函数过程中暂停和恢复执行。这种限制在某些情况下会导致代码的编写和处理异步任务的方式变得困难。Generator 函数的引入为解决这个问题提供了一种新的方式。
# 基本用法
- 函数声明:
Generator 函数的定义使用 function* 关键字,例如:
function* myGenerator() {
// Generator 函数体
}
2
3
- Yield 表达式:
Generator 函数内部使用 yield 关键字来定义暂停点,将函数的执行暂停,并返回一个值给外部调用者。例如:
function* myGenerator() {
yield 1;
yield 2;
yield 3;
}
2
3
4
5
- 迭代器对象:
当调用 Generator 函数时,它返回一个迭代器对象。这个迭代器对象有一个特殊的方法 next(),用于控制 Generator 函数的执行和获取产生的值。 - 迭代器的 next() 方法:
迭代器对象的 next() 方法用于执行 Generator 函数,并返回一个对象,其中包含两个属性:value 和 done。
- value:表示当前暂停点产生的值。
- done:表示函数是否已经执行完毕。
通过不断调用迭代器对象的 next() 方法,可以逐步执行 Generator 函数,并获取每个暂停点产生的值。
function* myGenerator() {
yield 1;
yield 2;
yield 3;
}
const generator = myGenerator(); // 调用 Generator 函数,得到迭代器对象
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: false }
console.log(generator.next()); // { value: undefined, done: true }
2
3
4
5
6
7
8
9
10
11
12
在这个示例中,首先调用 myGenerator() 返回一个迭代器对象 generator。然后通过不断调用 generator.next() 方法,执行 Generator 函数并获取产生的值。每次调用 next() 方法时,函数会执行到 yield 表达式,并返回暂停点的值。
通过这种方式,Generator 函数可以分步执行,每次产生一个值,并通过迭代器对象将值传递给外部调用者。这使得可以灵活地控制函数的执行和处理函数产生的结果。
# 迭代器
迭代器对象(Iterator)是一种提供按序访问集合或序列中元素的接口。它定义了一个 next() 方法,该方法在每次调用时返回一个包含两个属性的对象:value 和 done。value 表示当前迭代位置的值,done 表示迭代是否已经完成。
迭代器对象可以用于处理数据集合、序列或自定义数据结构。它提供了一种统一的方式来遍历和访问这些数据。
const myIterator = {
data: [1, 2, 3, 4, 5],
currentIndex: 0,
next() {
if (this.currentIndex < this.data.length) {
return {
value: this.data[this.currentIndex++],
done: false,
};
} else {
return {
done: true,
};
}
},
};
// 使用迭代器对象遍历数据
let result = myIterator.next();
while (!result.done) {
console.log(result.value);
result = myIterator.next();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
在这个示例中,myIterator对象是一个自定义的迭代器对象。它具有一个 data 属性,表示要迭代的数据集合,和一个 currentIndex 属性,表示当前的迭代位置。
迭代器对象定义了一个 next() 方法,每次调用该方法,它会检查当前的迭代位置是否小于数据集合的长度。如果是,就返回一个对象,其中 value 属性是当前位置的值,done 属性为 false。如果迭代位置超过了数据集合的长度,就返回一个对象,其中 done 属性为 true,表示迭代结束。
在使用迭代器对象时,可以通过不断调用 next() 方法来遍历数据集合。每次调用 next() 方法时,会获取当前位置的值并更新迭代位置。通过判断返回对象的 done 属性,可以确定迭代是否已经完成。
在上述示例中,我们通过一个简单的自定义迭代器对象 myIterator 遍历了数据集合 [1, 2, 3, 4, 5],并打印了每个元素的值。
总结来说,迭代器对象提供了一种通用的接口,用于按序访问集合或序列中的元素。它的 next() 方法返回一个包含 value 和 done 属性的对象,通过调用该方法可以逐步获取数据集合中的元素,并判断迭代是否已经完成。这种机制使得处理数据集合变得更加灵活和统一。