迭代器帮助器
00:00
Iterator Helpers提案详解
1. Iterator Helpers 概述
Iterator Helpers 是 TC39 提案,为迭代器添加了类似数组的高阶方法,使惰性计算链式操作成为可能。
// 传统方式:先转为数组再操作
const result = [...someIterator]
.filter((x) => x > 0)
.map((x) => x * 2)
.slice(0, 10);
// Iterator Helpers:惰性计算
const result = someIterator
.filter((x) => x > 0)
.map((x) => x * 2)
.take(10);
2. 可用方法
2.1 转换方法
function* numbers() {
let i = 0;
while (true) yield i++;
}
const iter = numbers();
// map — 转换每个元素
const doubled = iter.map((x) => x * 2);
// filter — 过滤元素
const evens = iter.filter((x) => x % 2 === 0);
// flatMap — 转换并展平
const pairs = iter.flatMap((x) => [x, x * 10]);
2.2 截取方法
// take — 取前 n 个
const first5 = numbers().take(5);
console.log([...first5]); // [0, 1, 2, 3, 4]
// drop — 跳过前 n 个
const after5 = numbers().drop(5).take(3);
console.log([...after5]); // [5, 6, 7]
2.3 终止方法
// reduce — 归约
const sum = numbers()
.take(5)
.reduce((acc, x) => acc + x, 0);
console.log(sum); // 10
// toArray — 转为数组
const arr = numbers().take(3).toArray();
console.log(arr); // [0, 1, 2]
// forEach — 遍历
numbers()
.take(3)
.forEach((x) => console.log(x));
// some / every
const hasEven = numbers()
.take(5)
.some((x) => x % 2 === 0);
const allPositive = numbers()
.take(5)
.every((x) => x >= 0);
// find
const found = numbers().find((x) => x > 3);
3. 惰性计算的优势
// 无限序列只需计算需要的部分
function* fibonacci() {
let a = 0,
b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
// 只计算前 10 个偶数斐波那契数
const evenFibs = fibonacci()
.filter((x) => x % 2 === 0)
.take(10)
.toArray();
console.log(evenFibs);
// [0, 2, 8, 34, 144, 610, 2584, 10946, 46368, 196418]
4. 与数组方法的区别
| 特性 | 数组方法 | Iterator Helpers |
|---|---|---|
| 计算 | 立即(eager) | 惰性(lazy) |
| 中间数组 | 每步创建 | 不创建 |
| 无限序列 | 不支持 | 支持 |
| 可重复消费 | (一次性) | |
| 索引访问 |
// 数组方式:3 个中间数组
const result1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
.filter((x) => x % 2 === 0) // [2, 4, 6, 8, 10]
.map((x) => x * 2) // [4, 8, 12, 16, 20]
.slice(0, 3); // [4, 8, 12]
// 迭代器方式:无中间数组
const result2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
.values()
.filter((x) => x % 2 === 0)
.map((x) => x * 2)
.take(3)
.toArray(); // [4, 8, 12]
5. 兼容性
Iterator Helpers 目前处于 Stage 3/4 阶段,主流浏览器正在逐步支持。可使用 core-js 或 polyfill-io 提前使用。