Skip to content

/**

  • 一个优雅的 async/await 实现。

  • 它的核心是一个接收 Generator 函数的转换器,

  • 返回一个能够自动执行该 Generator 的新函数。

  • @param {Function} generatorFunc - 一个 Generator 函数 (例如 function* myGen() { ... })

  • @returns {Function} - 一个新的函数,其行为与 async 函数一致,返回一个 Promise。 */ function asyncToGenerator(generatorFunc) { // 返回一个新的函数,这个函数就是我们模拟的 async 函数。 return function(...args) { // 1. 调用原始的 generator 函数,获取一个 generator 对象(迭代器)。 // 使用 apply 来确保正确的 this 指向和参数传递。 const gen = generatorFunc.apply(this, args);

    // 2. 返回一个 Promise,这是 async 函数的标配。 return new Promise((resolve, reject) => {

    /** * 内部的“执行器”函数,负责驱动 generator 的执行。 * @param {String} key - 'next' 或 'throw',决定是正常执行还是抛出异常。 * @param {*} arg - 传递给 generator 的上一步的结果或错误。 */ function step(key, arg) { let generatorResult;

     // 3. 执行 generator,并捕获可能发生的同步错误。
     try {
       generatorResult = gen[key](arg); // 相当于 gen.next(arg) 或 gen.throw(arg)
     } catch (error) {
       // 如果 generator 内部出错,直接 reject 整个 Promise。
       return reject(error);
     }
    
     // 从执行结果中解构出 value 和 done。
     const { value, done } = generatorResult;
    
     if (done) {
       // 4. 如果 generator 执行完毕 (done is true),
       //    用最终的返回值 resolve 整个 Promise。
       return resolve(value);
     } else {
       // 5. 如果 generator 还未执行完毕,
       //    value 就是 yield 后面跟着的值(通常是一个 Promise)。
       //    我们用 Promise.resolve() 包装它,以兼容所有类型的值。
       return Promise.resolve(value).then(
         // 6. 当 Promise 成功时,将结果作为参数,继续下一步的执行。
         (res) => {
           step('next', res);
         },
         // 7. 当 Promise 失败时,将错误“抛”回 generator 内部,
         //    这样 generator 中的 try...catch 就可以捕获到。
         (err) => {
           step('throw', err);
         }
       );
     }
    

    }

    // 8. 启动执行器,开始第一步。 step('next'); }); }; }

// 模拟一个异步 API function sleep(ms, data) { return new Promise(resolve => setTimeout(() => resolve(data), ms)); }

// 使用 generator 函数来定义我们的异步流程 const myAsyncProcess = asyncToGenerator(function* (startValue) { console.log('开始执行,初始值:', startValue);

try { const result1 = yield sleep(1000, '结果1'); console.log('第一步完成:', result1);

const result2 = yield sleep(1500, '结果2');
console.log('第二步完成:', result2);

// 模拟一个失败的 Promise
// yield Promise.reject('出错了!');

return '全部执行成功!';

} catch (e) { console.error('在 Generator 内部捕获到错误:', e); return '执行失败'; } });

// 调用我们“创建”的 async 函数 myAsyncProcess('Hello').then(finalResult => { console.log('Promise 的最终结果:', finalResult); });

// --- 控制台输出 --- // 开始执行,初始值: Hello // (等待 1 秒) // 第一步完成: 结果1 // (等待 1.5 秒) // 第二步完成: 结果2 // Promise 的最终结果: 全部执行成功!

本站访客数 人次 本站总访问量