迭代器是一个对象,它实现了以下接口:
interface Iterator {
next(): {
value: any, // 当前值
done: boolean, // 是否完成迭代
};
}
// 手动创建迭代器
const simpleIterator = {
data: [1, 2, 3],
index: 0,
next() {
if (this.index < this.data.length) {
return { value: this.data[this.index++], done: false };
}
return { value: undefined, done: true };
},
};
console.log(simpleIterator.next()); // {value: 1, done: false}
console.log(simpleIterator.next()); // {value: 2, done: false}
console.log(simpleIterator.next()); // {value: 3, done: false}
console.log(simpleIterator.next()); // {value: undefined, done: true}
// 带 return 和 throw 方法的迭代器
const advancedIterator = {
data: [1, 2, 3, 4, 5],
index: 0,
next() {
if (this.index < this.data.length) {
return { value: this.data[this.index++], done: false };
}
return { done: true };
},
return(value) {
console.log("迭代器提前终止");
this.index = this.data.length; // 标记为完成
return { value, done: true };
},
throw(error) {
console.log("迭代器抛出错误:", error);
return { done: true };
},
};
const it = advancedIterator;
console.log(it.next()); // {value: 1, done: false}
console.log(it.return()); // 迭代器提前终止, {done: true}
console.log(it.next()); // {done: true}
// 实现 Symbol.iterator 方法
const myIterable = {
items: ["a", "b", "c"],
[Symbol.iterator]() {
let index = 0;
const items = this.items;
return {
next() {
if (index < items.length) {
return { value: items[index++], done: false };
}
return { done: true };
},
return(value) {
console.log("提前终止");
return { value, done: true };
},
};
},
};
// 使用 for...of 遍历
for (let item of myIterable) {
console.log(item); // a, b, c
}
// 使用展开运算符
console.log([...myIterable]); // ['a', 'b', 'c']
// 使用解构赋值
const [first, second] = myIterable;
console.log(first, second); // a b
// 数组
const arr = [1, 2, 3];
console.log(arr[Symbol.iterator]); // ƒ values() { [native code] }
// 字符串
const str = "hello";
const strIterator = str[Symbol.iterator]();
console.log(strIterator.next()); // {value: 'h', done: false}
// Map
const map = new Map([
["a", 1],
["b", 2],
]);
const mapIterator = map[Symbol.iterator]();
console.log(mapIterator.next()); // {value: ['a', 1], done: false}
// Set
const set = new Set([1, 2, 3]);
const setIterator = set[Symbol.iterator]();
console.log(setIterator.next()); // {value: 1, done: false}
// NodeList
const nodeList = document.querySelectorAll("div");
const nodeIterator = nodeList[Symbol.iterator]();
// 范围迭代器
class Range {
constructor(start, end, step = 1) {
this.start = start;
this.end = end;
this.step = step;
}
[Symbol.iterator]() {
let current = this.start;
const end = this.end;
const step = this.step;
return {
next() {
if ((step > 0 && current <= end) || (step < 0 && current >= end)) {
const value = current;
current += step;
return { value, done: false };
}
return { done: true };
},
return(value) {
console.log("范围迭代提前终止");
return { value, done: true };
},
};
}
}
const range = new Range(1, 5);
for (let num of range) {
console.log(num); // 1, 2, 3, 4, 5
}
// 反向范围
const reverseRange = new Range(5, 1, -1);
console.log([...reverseRange]); // [5, 4, 3, 2, 1]
// 无限迭代器
class InfiniteSequence {
constructor(start = 0, step = 1) {
this.start = start;
this.step = step;
}
[Symbol.iterator]() {
let current = this.start;
const step = this.step;
return {
next() {
const value = current;
current += step;
return { value, done: false };
},
};
}
}
const naturalNumbers = new InfiniteSequence(1);
const iterator = naturalNumbers[Symbol.iterator]();
console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3
// ... 无限继续
// 定义生成器函数
function* generatorFunction() {
console.log("开始执行");
yield 1;
console.log("第一次暂停后继续");
yield 2;
console.log("第二次暂停后继续");
yield 3;
console.log("结束执行");
return 4;
}
// 创建生成器对象
const generator = generatorFunction();
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: 4, done: true}
console.log(generator.next());
// {value: undefined, done: true}
function* expressionDemo() {
const input = yield "请输入值:";
console.log("收到的输入:", input);
const result = yield `处理结果: ${input * 2}`;
console.log("最终结果:", result);
return "完成";
}
const gen = expressionDemo();
console.log(gen.next()); // {value: '请输入值:', done: false}
console.log(gen.next(10)); // 收到的输入: 10, {value: '处理结果: 20', done: false}
console.log(gen.next(30)); // 最终结果: 30, {value: '完成', done: true}
// yield* 委托给另一个生成器
function* innerGenerator() {
yield "inner 1";
yield "inner 2";
}
function* outerGenerator() {
yield "outer start";
yield* innerGenerator(); // 委托
yield "outer end";
}
for (let value of outerGenerator()) {
console.log(value); // outer start, inner 1, inner 2, outer end
}
// yield* 也可以委托给可迭代对象
function* delegateToArray() {
yield* [1, 2, 3];
yield* "abc";
}
console.log([...delegateToArray()]); // [1, 2, 3, 'a', 'b', 'c']
function* methodsDemo() {
try {
yield 1;
yield 2;
yield 3;
} catch (error) {
console.log("捕获到错误:", error);
yield "错误恢复";
} finally {
console.log("清理工作");
}
}
const gen = methodsDemo();
console.log(gen.next()); // {value: 1, done: false}
console.log(gen.throw(new Error("测试错误")));
// 捕获到错误: Error: 测试错误
// {value: '错误恢复', done: false}
console.log(gen.next()); // 清理工作, {value: undefined, done: true}
// return 方法
const gen2 = methodsDemo();
console.log(gen2.next()); // {value: 1, done: false}
console.log(gen2.return("提前结束")); // 清理工作, {value: '提前结束', done: true}
console.log(gen2.next()); // {value: undefined, done: true}
// 1. 惰性计算(无限序列)
function* fibonacci(limit = Infinity) {
let [prev, curr] = [0, 1];
let count = 0;
while (count < limit) {
yield curr;
[prev, curr] = [curr, prev + curr];
count++;
}
}
// 获取前10个斐波那契数
const fib10 = [...fibonacci(10)];
console.log(fib10); // [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
// 2. 状态机
function* trafficLight() {
while (true) {
yield "红色 - 停止";
yield "绿色 - 通行";
yield "黄色 - 注意";
}
}
const light = trafficLight();
console.log(light.next().value); // 红色 - 停止
console.log(light.next().value); // 绿色 - 通行
console.log(light.next().value); // 黄色 - 注意
// 3. 数据管道
function* filter(source, predicate) {
for (let item of source) {
if (predicate(item)) {
yield item;
}
}
}
function* map(source, transform) {
for (let item of source) {
yield transform(item);
}
}
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 组合管道
const pipeline = map(
filter(numbers, n => n % 2 === 0), // 过滤偶数
n => n * 2 // 乘以2
);
console.log([...pipeline]); // [4, 8, 12, 16, 20]
// 创建异步迭代器
const asyncIterable = {
data: [1, 2, 3],
[Symbol.asyncIterator]() {
let index = 0;
const data = this.data;
return {
async next() {
// 模拟异步操作
await new Promise(resolve => setTimeout(resolve, 1000));
if (index < data.length) {
return { value: data[index++], done: false };
}
return { done: true };
},
async return(value) {
console.log("异步迭代器提前终止");
return { value, done: true };
},
async throw(error) {
console.log("异步迭代器错误:", error);
throw error;
},
};
},
};
// 使用 for await...of
(async () => {
for await (let value of asyncIterable) {
console.log(value); // 1 (1秒后), 2 (1秒后), 3 (1秒后)
}
})();
// 手动调用
async function manualIteration() {
const iterator = asyncIterable[Symbol.asyncIterator]();
console.log(await iterator.next()); // {value: 1, done: false}
console.log(await iterator.next()); // {value: 2, done: false}
console.log(await iterator.next()); // {value: 3, done: false}
console.log(await iterator.next()); // {done: true}
}
// 异步生成器函数
async function* asyncGenerator(limit) {
for (let i = 1; i <= limit; i++) {
// 模拟异步操作
await new Promise(resolve => setTimeout(resolve, 500));
yield i;
}
return "完成";
}
// 使用异步生成器
(async () => {
const gen = asyncGenerator(5);
console.log(await gen.next()); // {value: 1, done: false} (500ms后)
console.log(await gen.next()); // {value: 2, done: false} (500ms后)
console.log(await gen.next()); // {value: 3, done: false} (500ms后)
// 使用 for await...of
for await (let value of asyncGenerator(3)) {
console.log("值:", value); // 值: 1, 值: 2, 值: 3
}
})();
// 实际应用:分页获取数据
async function* paginatedData(url) {
let page = 1;
let hasMore = true;
while (hasMore) {
// 模拟 API 调用
const response = await fetch(`${url}?page=${page}`);
const data = await response.json();
yield data.items;
hasMore = data.hasMore;
page++;
}
}
// 使用示例
(async () => {
const pages = paginatedData("https://api.example.com/data");
for await (let items of pages) {
console.log("获取到数据:", items);
// 处理每一页的数据
if (items.length === 0) {
break; // 没有数据时中断
}
}
})();
// 迭代器工具函数
function take(iterator, n) {
return {
[Symbol.iterator]() {
const it = iterator[Symbol.iterator]();
let count = 0;
return {
next() {
if (count < n) {
count++;
return it.next();
}
return { done: true };
},
return(value) {
if (typeof it.return === "function") {
it.return(value);
}
return { value, done: true };
},
};
},
};
}
function filter(iterator, predicate) {
return {
[Symbol.iterator]() {
const it = iterator[Symbol.iterator]();
return {
next() {
while (true) {
const result = it.next();
if (result.done || predicate(result.value)) {
return result;
}
}
},
return(value) {
if (typeof it.return === "function") {
it.return(value);
}
return { value, done: true };
},
};
},
};
}
// 创建无限序列
function* naturalNumbers() {
let n = 1;
while (true) {
yield n++;
}
}
// 组合使用:获取前5个偶数的平方
const result = take(
filter(naturalNumbers(), n => n % 2 === 0),
5
);
console.log([...result]); // [2, 4, 6, 8, 10]
// 使用生成器控制异步流程
function asyncFlow(generatorFunction) {
return function (...args) {
const generator = generatorFunction(...args);
function handle(result) {
if (result.done) {
return Promise.resolve(result.value);
}
return Promise.resolve(result.value)
.then(res => handle(generator.next(res)))
.catch(err => handle(generator.throw(err)));
}
return handle(generator.next());
};
}
// 示例使用
const fetchData = asyncFlow(function* () {
try {
console.log("开始获取用户数据...");
const user = yield fetch("/api/user").then(res => res.json());
console.log("用户:", user);
console.log("开始获取订单数据...");
const orders = yield fetch(`/api/orders/${user.id}`).then(res => res.json());
console.log("订单:", orders);
return { user, orders };
} catch (error) {
console.error("错误:", error);
throw error;
}
});
// 使用 async/await 的现代写法
async function fetchDataModern() {
try {
console.log("开始获取用户数据...");
const userResponse = await fetch("/api/user");
const user = await userResponse.json();
console.log("用户:", user);
console.log("开始获取订单数据...");
const ordersResponse = await fetch(`/api/orders/${user.id}`);
const orders = await ordersResponse.json();
console.log("订单:", orders);
return { user, orders };
} catch (error) {
console.error("错误:", error);
throw error;
}
}
// 使用生成器实现观察者模式
function createObservable(subscriber) {
return {
subscribe(observer) {
const generator = subscriber(observer);
generator.next(); // 启动生成器
return {
unsubscribe() {
generator.return();
},
};
},
};
}
// 使用示例
const observable = createObservable(function* (observer) {
try {
let count = 0;
const interval = setInterval(() => {
observer.next(count++);
}, 1000);
// 清理函数
yield; // 暂停,等待取消订阅
clearInterval(interval);
observer.complete();
} catch (error) {
observer.error(error);
}
});
const subscription = observable.subscribe({
next(value) {
console.log("收到值:", value);
},
error(err) {
console.error("错误:", err);
},
complete() {
console.log("完成");
},
});
// 5秒后取消订阅
setTimeout(() => {
subscription.unsubscribe();
console.log("已取消订阅");
}, 5000);
// 简单的协程调度器
function createScheduler() {
const tasks = [];
let running = false;
function addTask(generator) {
return new Promise((resolve, reject) => {
tasks.push({ generator, resolve, reject });
if (!running) {
run();
}
});
}
async function run() {
running = true;
while (tasks.length > 0) {
const task = tasks.shift();
try {
const result = await runTask(task.generator);
task.resolve(result);
} catch (error) {
task.reject(error);
}
}
running = false;
}
async function runTask(generator) {
let result = generator.next();
while (!result.done) {
const value = result.value;
if (value instanceof Promise) {
result = generator.next(await value);
} else if (typeof value === "function") {
result = generator.next(value());
} else {
result = generator.next(value);
}
}
return result.value;
}
return { addTask };
}
// 使用示例
const scheduler = createScheduler();
function* taskA() {
console.log("任务A开始");
yield new Promise(resolve => setTimeout(resolve, 1000));
console.log("任务A继续");
yield new Promise(resolve => setTimeout(resolve, 1000));
console.log("任务A完成");
return "A的结果";
}
function* taskB() {
console.log("任务B开始");
yield new Promise(resolve => setTimeout(resolve, 500));
console.log("任务B完成");
return "B的结果";
}
// 并行执行任务
Promise.all([scheduler.addTask(taskA()), scheduler.addTask(taskB())]).then(results => {
console.log("所有任务完成:", results);
});
// 常用迭代器工具函数
const Iter = {
// 从数组创建迭代器
fromArray(arr) {
let index = 0;
return {
next() {
if (index < arr.length) {
return { value: arr[index++], done: false };
}
return { done: true };
},
[Symbol.iterator]() {
return this;
},
};
},
// 范围迭代器
range(start, end, step = 1) {
let current = start;
return {
next() {
if ((step > 0 && current <= end) || (step < 0 && current >= end)) {
const value = current;
current += step;
return { value, done: false };
}
return { done: true };
},
[Symbol.iterator]() {
return this;
},
};
},
// 无限迭代器
infinite(start = 0, step = 1) {
let current = start;
return {
next() {
const value = current;
current += step;
return { value, done: false };
},
[Symbol.iterator]() {
return this;
},
};
},
// 映射
map(iterable, fn) {
const iterator = iterable[Symbol.iterator]();
return {
next() {
const result = iterator.next();
if (!result.done) {
return { value: fn(result.value), done: false };
}
return { done: true };
},
[Symbol.iterator]() {
return this;
},
};
},
// 过滤
filter(iterable, predicate) {
const iterator = iterable[Symbol.iterator]();
return {
next() {
while (true) {
const result = iterator.next();
if (result.done || predicate(result.value)) {
return result;
}
}
},
[Symbol.iterator]() {
return this;
},
};
},
// 归约
reduce(iterable, reducer, initialValue) {
const iterator = iterable[Symbol.iterator]();
let accumulator = initialValue;
let index = 0;
while (true) {
const result = iterator.next();
if (result.done) {
break;
}
accumulator = reducer(accumulator, result.value, index++);
}
return accumulator;
},
// 转换为数组
toArray(iterable) {
const result = [];
for (let value of iterable) {
result.push(value);
}
return result;
},
};
// 使用示例
const numbers = Iter.range(1, 10);
const doubled = Iter.map(numbers, n => n * 2);
const evens = Iter.filter(doubled, n => n % 4 === 0);
const sum = Iter.reduce(evens, (acc, n) => acc + n, 0);
console.log(Iter.toArray(evens)); // [4, 8, 12, 16, 20]
console.log(sum); // 60
// 常用生成器工具函数
const Gen = {
// 组合多个生成器
*concat(...generators) {
for (let gen of generators) {
yield* gen;
}
},
// 压缩多个生成器
*zip(...generators) {
while (true) {
const results = generators.map(gen => gen.next());
if (results.some(result => result.done)) {
break;
}
yield results.map(result => result.value);
}
},
// 无限重复
*repeat(value) {
while (true) {
yield value;
}
},
// 循环
*cycle(iterable) {
const values = [...iterable];
while (true) {
for (let value of values) {
yield value;
}
}
},
// 生成器转异步
async *toAsync(generator) {
for (let value of generator) {
yield await Promise.resolve(value);
}
},
// 批量处理
*batch(iterable, size) {
let batch = [];
for (let item of iterable) {
batch.push(item);
if (batch.length === size) {
yield batch;
batch = [];
}
}
if (batch.length > 0) {
yield batch;
}
},
};
// 使用示例
// 合并生成器
function* gen1() {
yield 1;
yield 2;
}
function* gen2() {
yield 3;
yield 4;
}
console.log([...Gen.concat(gen1(), gen2())]); // [1, 2, 3, 4]
// 压缩
console.log([...Gen.zip(gen1(), gen2())]); // [[1, 3], [2, 4]]
// 批量处理
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9];
for (let batch of Gen.batch(data, 3)) {
console.log("批次:", batch);
// [1, 2, 3], [4, 5, 6], [7, 8, 9]
}
// 避免在热路径中创建迭代器
// 不好
function sumArray(arr) {
let sum = 0;
for (let value of arr) { // 每次循环都创建迭代器
sum += value;
}
return sum;
}
// 好
function sumArrayFast(arr) {
let sum = 0;
for (let i = 0, len = arr.length; i < len; i++) {
sum += arr[i];
}
return sum;
}
// 使用生成器处理大数据集
function* processLargeDataset(dataset) {
for (let item of dataset) {
// 处理每个项目
const processed = expensiveOperation(item);
yield processed;
// 可以添加暂停点,避免阻塞主线程
if (needsYield()) {
await new Promise(resolve => setTimeout(resolve, 0));
}
}
}
// 安全的迭代器遍历
function safeIterate(iterable, callback) {
const iterator = iterable[Symbol.iterator]();
try {
while (true) {
const result = iterator.next();
if (result.done) {
break;
}
callback(result.value);
}
} catch (error) {
console.error("迭代出错:", error);
// 尝试清理
if (typeof iterator.return === "function") {
iterator.return();
}
throw error;
} finally {
// 确保资源释放
if (typeof iterator.return === "function") {
iterator.return();
}
}
}
// 使用示例
const iterable = {
[Symbol.iterator]() {
let count = 0;
return {
next() {
if (count++ === 3) {
throw new Error("模拟错误");
}
return { value: count, done: false };
},
return() {
console.log("清理资源");
return { done: true };
},
};
},
};
try {
safeIterate(iterable, value => {
console.log("处理:", value);
});
} catch (error) {
console.error("捕获到错误:", error.message);
}
// 流式处理大数据
async function* processStream(stream) {
const reader = stream.getReader();
const decoder = new TextDecoder();
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
const chunk = decoder.decode(value, { stream: true });
yield chunk;
}
} finally {
reader.releaseLock();
console.log("流处理完成,资源已释放");
}
}
// 使用示例
async function handleLargeFile() {
const response = await fetch("large-file.txt");
const stream = response.body;
for await (let chunk of processStream(stream)) {
// 处理每个块,而不是一次性加载整个文件
console.log("收到块:", chunk.length, "字节");
// 可以在处理过程中暂停
if (needsBreak()) {
break;
}
}
}
迭代器和生成器是 JavaScript 中强大的功能,它们提供了: