JS: 模拟async/await语法糖

不熟悉生成器对象的小伙伴,可查看:GeneratorGenerator.prototype.next

基于Generator和Promise实现 async(async是自带自动执行器的Generator迭代器函数)

模拟函数

复制代码
/**
 * 自动执行的迭代器函数
 * (不返回Promise对象也是可以的)
 * @param generator 
 * @return {Promise} 
 */
const run = generator => {
  return new Promise((resolve, reject) => {
    // 获取iterator对象(可迭代对象)
    const gen = generator();
    // 初始化iterator对象的next指针
    let next = null;
    /**
     * 执行下一步
     * @param {Iterator} genNextFn - gen.next函数
     * @return {undefined} 
     */
    const goToNextStep = genNextFn => {
      try {
        // 更新next指针
        next = genNextFn();
      }
      catch(ex) {
        reject(ex);
        return;
      }
      // 如果完成了对iterator的遍历
      if (next?.done === true) {
        resolve(next.value);
        return;
      }
      // 否则,递归执行下一步
      Promise.resolve(next.value)
        .then(v => goToNextStep(() => gen.next(v)))
        .catch(e => goToNextStep(() => gen.next(e)));
    };
    goToNextStep(() => gen.next());
  });
};

const runMiniAsync = () => run(function* () {
  const r1 = yield new Promise(resolve => setTimeout(() => resolve(1), 800));
  console.log('===>', r1);
  const r0 = 'x';
  console.log('->', r0);
  const r2 = yield new Promise(resolve => setTimeout(() => resolve(2), 600));
  console.log('==>', r2);
});

runMiniAsync();
复制代码

 

模拟函数执行过程示意:

复制代码
// gen -> Iterator{}
// next -> null
// goToNextStep()
// next -> { value: Promise{1}, done: false }
// ::fulfilled(1)
// goToNextStep()
//// => yield 1
// next -> { value: Promise{2}, done: false }
// ::fulfilled(2)
// goToNextStep()
//// => yield 2
// next -> { value: undefined, done: true }
// ::end
复制代码

 

posted @   樊顺  阅读(132)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示