ES6 Generator函数的异步应用 (八)

ES6 Generator 函数的异步应用主要通过与 Promise 配合使用来实现。这种模式被称为 "thunk" 模式,它允许你编写看起来是同步的异步代码。

特性:

  1. 暂停执行:当 Generator 函数遇到 yield 表达式时,它会暂停执行,等待 Promise 解决。
  2. 恢复执行:当 Promise 完成(解决或拒绝)时,Generator 函数恢复执行,并返回 yield 表达式的结果。
  3. 错误处理:可以对异步操作中的错误进行捕获和处理。
  4. 链式调用:可以创建一个链式的异步操作,每个操作都在前一个操作完成后开始。

1. 基本的异步 Generator 函数

javascript 复制代码
function delay(time) {
    return new Promise(resolve => setTimeout(resolve, time));
}

function* asyncGenerator() {
    console.log("Start");
    yield delay(1000); // 等待1秒
    console.log("After 1 second");
    yield delay(1000); // 再等待1秒
    console.log("After another second");
    return "Done";
}

let gen = asyncGenerator();

function runGenerator(g) {
    let result = g.next();
    result.value.then(() => {
        if (!result.done) {
            runGenerator(g);
        }
    });
}

runGenerator(gen);

2. 使用 for...of 和 async...await 语法糖

javascript 复制代码
// 假设我们有以下 async generator
async function* asyncGen() {
    yield await Promise.resolve(1);
    yield await Promise.resolve(2);
    yield await Promise.resolve(3);
}

// 我们可以使用 for...of 循环和 async...await 语法糖来简化调用
(async () => {
    for await (let value of asyncGen()) {
        console.log(value); // 依次输出 1, 2, 3
    }
})();

3. 处理异步操作中的错误

javascript 复制代码
function* asyncGenWithError() {
    try {
        yield Promise.reject("Error occurred!");
    } catch (e) {
        console.log(e); // 输出:Error occurred!
    }
}

let genWithError = asyncGenWithError();

genWithError.next().value.catch(err => console.log(err));

4. 使用 yield* 委托给其他异步 Generator 函数

javascript 复制代码
function* innerAsyncGen() {
    yield Promise.resolve("A");
    yield Promise.resolve("B");
}

function* outerAsyncGen() {
    yield "Start";
    yield* innerAsyncGen(); // 委托给另一个异步 Generator 函数
    yield "End";
}

let outerGen = outerAsyncGen();

function runOuterGenerator(g) {
    let result = g.next();
    result.value.then(val => {
        if (!result.done) {
            runOuterGenerator(g);
        }
    });
}

runOuterGenerator(outerGen);
相关推荐
陈随易2 小时前
在Finch用了62亿词元,我认为这是新一代Agent工具之神
前端·人工智能·后端
水域安全老周2 小时前
水趣钓鱼救生衣专利拆解:两级锁紧如何解决落水人衣分离
java·前端·网络
计算机魔术师3 小时前
Anthropic CEO突然喊踩刹车,OpenAI罕见力挺:AI这辆车不能只踩油门了
前端
wing983 小时前
从codex转战workbuddy使用一周的感受
前端·人工智能·后端
Highcharts.js3 小时前
常见报错排雷指南2:导出失败的官方解法
javascript·react.js·ecmascript·highcharts·可视化图表·导出模块失败·导出服务
EatFan3 小时前
Java接入支付宝 JSAPI 支付保姆教程(二):流程讲解与前后端代码讲解
前端·spring boot·后端·微信小程序·小程序·uni-app
梦想平凡4 小时前
百游棋牌源代码开发搭建教程(五):房间创建、座位分配与请求幂等实现
前端·javascript·数据库·源代码管理
IT_陈寒4 小时前
Redis的Set操作居然能把我的服务整挂了?
前端·人工智能·后端
计算机魔术师4 小时前
Suno 发布 v6 音乐模型,推出 v6、v6-wild、v6-mini 三个版本
前端
whyweplay5 小时前
elpis : DSL动态组件学习
前端