首页 > 其他分享 >JS: 模拟async/await语法糖

JS: 模拟async/await语法糖

时间:2022-09-07 19:48:06浏览次数:99  
标签:resolve const await next goToNextStep Promise async JS gen

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

模拟函数:

/**
 * 模拟async关键字的函数
 * (不返回Promise对象也是可以的)
 * @param generator 
 * @return {Promise} 
 */
const _async = 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 = () => _async(function* () {
  const r1 = yield new Promise(resolve => setTimeout(() => resolve(1), 800));
  console.log('===>', r1);
  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

 

标签:resolve,const,await,next,goToNextStep,Promise,async,JS,gen
From: https://www.cnblogs.com/fanqshun/p/16667026.html

相关文章

  • 包和模块、库、json库
    七.包和模块package:针对代码结构的组织,一个包里面可以拥有很多的python文件module:一个python文件就是一个模块1.从另一个模块直接引用所需代码模块必须是存放在......
  • js 实现扁平数组转为树形结构数组及树形结构数组转为扁平数组
    //pid代表属于的父级id//id代表的是自己本身的id,本身的id是多少letflatArr=[{id:1,name:"部门1",pid:0},{id:2,name:"部门2",pid:1}......
  • vue.js3:图片镜像(翻转)并保存([email protected])
    一,js代码:<template><divstyle="background:#ffffff;"id="root"><div><button@click="restore">还原</button><button@click="flipx">水平镜像</button>......
  • autojs
    functionunlock(){if(!device.isScreenOn()){device.wakeUp();sleep(500);swipe(500,2000,500,1000,210);sleep(500)......
  • 4.JS内部对象
    4.内部对象标准对象4.1Date typeof123 'number' typeof'123' 'string' typeoftrue 'boolean' typeofNaN 'number' typeof[] 'object' typeof{} 'o......
  • JS笔记
     1.js获取map的键:bosType:"353E3C6E"dynamic_Field37:falsedynamic_Field39:bankAccountNumber:"45001604255060414843"bosType:"FB326E5E"id:"KggAA......
  • js - script标签的for属性和event属性
    js-script标签的for属性和event属性<scriptlanguage="javascript"for="window"event="onload">alert("helloword!");</script>//for属性指定脚本执行对象(给......
  • Js学习之------空对象{}和null是否全等?
      null是一个空的引用,它和对象原型链的顶端全等,因为原型链的顶端就是一个空的引用而空对象虽然没有实际内容,但是它有原型链,所以两者不相等......
  • javascript 过滤字符串中script并且替换掉 xss注入攻击+js调试
    最近发现网上找答案也是80%类似结果。js调试可以在浏览器里,f10,f11可以比较准确。functionscriptReplace(str){if(newRegExp(".*?script[^>]*?.*?(<\/.*?sc......
  • js四种异步方法(回调函数、Promise、Generator、async/await)
    由于JS运行环境是单线程的,即一次只能完成一个任务,所以多任务时需要排队。异步可以理解为改变执行顺序的操作,异步任务必须在同步任务执行结束之后,从任务队列中依次取出执行......