JavaScript中的生成器(Generator)和异步生成器(Async Generator)都是用于实现自定义迭代行为的特性,但两者的设计目标和执行逻辑存在明显区别,下面从多个维度展开分析。

基础语法差异
生成器的定义需要在函数名前加*,内部使用yield关键字暂停执行并返回值;异步生成器则需要在函数名前同时加async和*,内部使用yield返回异步操作的结果,返回值默认是Promise对象。
普通生成器的基础定义示例如下:
// 普通生成器定义
function* normalGenerator() {
yield 1;
yield 2;
yield 3;
}
// 使用生成器
const gen = normalGenerator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }
异步生成器的基础定义示例如下:
// 异步生成器定义
async function* asyncGenerator() {
yield new Promise(resolve => setTimeout(() => resolve(1), 1000));
yield new Promise(resolve => setTimeout(() => resolve(2), 1000));
yield new Promise(resolve => setTimeout(() => resolve(3), 1000));
}
// 使用异步生成器
async function runAsyncGen() {
const asyncGen = asyncGenerator();
console.log(await asyncGen.next()); // { value: 1, done: false }
console.log(await asyncGen.next()); // { value: 2, done: false }
console.log(await asyncGen.next()); // { value: 3, done: false }
console.log(await asyncGen.next()); // { value: undefined, done: true }
}
runAsyncGen();
执行机制区别
普通生成器的next()方法执行是同步的,调用后会立即返回当前yield的值,不会等待任何异步操作完成。生成器的迭代过程完全由调用方控制,每次调用next()才会执行到下一个yield位置。
异步生成器的next()方法返回的是一个Promise对象,这个Promise会在当前yield后面的异步操作完成后才会决议,返回对应的值。如果需要在循环中处理异步生成器的返回值,通常需要配合for await...of语法使用。
异步生成器的迭代示例如下:
async function* fetchDataGenerator() {
const urls = ['https://ipipp.com/api/data1', 'https://ipipp.com/api/data2'];
for (const url of urls) {
// 模拟异步请求
const data = await new Promise(resolve => {
setTimeout(() => resolve(`data from ${url}`), 500);
});
yield data;
}
}
async function consumeAsyncGen() {
for await (const data of fetchDataGenerator()) {
console.log(data); // 依次输出两个接口的数据
}
}
consumeAsyncGen();
返回值类型差异
普通生成器调用next()返回的是{ value: any, done: boolean }格式的对象,其中value是yield后面跟的表达式的结果,类型可以是任意JavaScript类型。
异步生成器调用next()返回的是Promise对象,该Promise决议后的结果才是{ value: any, done: boolean }格式的对象,其中value是yield后面跟的Promise决议后的值。
适用场景对比
两者的适用场景有明显区分:
- 普通生成器适合处理同步的惰性迭代场景,比如需要按需生成大量数据、实现自定义的可迭代对象、简化复杂循环的编写等,不需要等待异步操作的场景都可以使用。
- 异步生成器适合处理异步数据流的迭代场景,比如需要依次请求多个接口、读取大文件的异步分块、处理实时推送的异步消息等,需要结合异步操作的迭代逻辑优先选择异步生成器。
共同特性
两者也有一些共同的特性:
- 都实现了迭代器协议,都可以被
for...of(异步生成器需要for await...of)循环遍历。 - 都可以通过
return()方法提前终止迭代,通过throw()方法向生成器内部抛出异常。 - 都支持在函数内部使用
return语句返回最终值,该值会出现在最后一次next()调用的value中,同时done变为true。
在实际开发中,需要根据是否需要处理异步操作来选择对应的生成器类型,避免在不必要的场景下使用异步生成器增加代码复杂度,也不要在需要异步迭代的场景下错误使用普通生成器导致逻辑异常。
GeneratorAsync_GeneratorJavaScript异步编程修改时间:2026-07-03 15:27:32