yield 模拟 async/await
您说得对!Generator 的 yield 配合执行器确实可以模拟 await 的效果。让我用一个更直观的例子展示这种对应关系。
Generator 模拟 async/await
// 模拟异步函数
function delay(ms, value) {
return new Promise(resolve => setTimeout(() => resolve(value), ms));
}
// Generator函数(类似async函数)
function* asyncTask() {
console.log('开始任务');
const result1 = yield delay(1000, '第一步完成');
console.log(result1);
const result2 = yield delay(1500, '第二步完成');
console.log(result2);
return '任务完成';
}
// 执行器(类似await的底层实现)
function runGenerator(genFn) {
const iterator = genFn();
function handle(result) {
if (result.done) return Promise.resolve(result.value);
return Promise.resolve(result.value)
.then(res => handle(iterator.next(res)))
.catch(err => iterator.throw(err));
}
return handle(iterator.next());
}
// 执行Generator
runGenerator(asyncTask).then(finalResult => {
console.log('最终结果:', finalResult);
});
与async/await的对应关系
| Generator写法 | async/await写法 | 说明 |
|---|---|---|
function* |
async function |
声明异步函数 |
yield |
await |
暂停执行等待Promise |
runGenerator |
JavaScript引擎内置 | 自动执行器 |
转换为async/await版本
// 同样的异步函数
function delay(ms, value) {
return new Promise(resolve => setTimeout(() => resolve(value), ms));
}
// async/await版本
async function asyncTask() {
console.log('开始任务');
const result1 = await delay(1000, '第一步完成');
console.log(result1);
const result2 = await delay(1500, '第二步完成');
console.log(result2);
return '任务完成';
}
// 直接调用
asyncTask().then(finalResult => {
console.log('最终结果:', finalResult);
});
关键区别
-
语法糖:
- async/await是Generator+P执行器的语法糖
- 不需要手动写执行器
-
错误处理:
// Generator版本 function* task() { try { const res = yield asyncOp(); } catch(err) { // 处理错误 } } // async/await版本 async function task() { try { const res = await asyncOp(); } catch(err) { // 处理错误 } } -
返回值:
- Generator函数返回迭代器
- async函数返回Promise
历史发展
- 回调地狱 → 2. Promise → 3. Generator → 4. async/await
Generator是JavaScript异步编程演进过程中的重要一步,它让开发者可以用同步的方式写异步代码,最终演变成了更简洁的async/await语法。

浙公网安备 33010602011771号