热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

用Generator函数和Promise对async/await进行模拟与转换

Talkischeap,showyouthecode异步函数1functiondoLazy1(){returnnewPromise((rs,rj){setTimeout((){

Talk is cheap,show you the code

//异步函数1
function doLazy1() {
return new Promise((rs, rj) => {
setTimeout(() => {
console.log('do Lazy1');
rs();
}, 1000)
})
}
//异步函数2
function doLazy2() {
return new Promise((rs, rj) => {
setTimeout(() => {
console.log('do Lazy2');
rs();
}, 2000)
})
}
//同步函数
function doNow() {
console.log('do now!');
return 'now'
}
async function doAsync() {
console.log('start');
await doLazy1();
console.log('after Lazy1');
await doLazy2();
console.log('after Lazy2');
const res = await doNow();
console.log('after now');
return res;
}
doAsync();
//打印出:
// start
// do Lazy1
// after Lazy1
// do Lazy2
// after Lazy2
// do now!
// after now
// 表达式输出为
// "now"
console.log('-----------------');
function runGenerator(generator) {
const task = generator();
let lastStep = task.next();
function stepFoward() {
if (lastStep.dOne=== false) {
return Promise.resolve(lastStep.value).then((res) => {
lastStep = task.next(res);
return stepFoward();
})
} else {
console.log('done')
return Promise.resolve(lastStep.value)
}
}
return stepFoward();
}
//doAsync被转换成:
runGenerator(function* doAsyncFromGenerator() {
console.log('start');
yield doLazy1();
console.log('after Lazy1');
yield doLazy2();
console.log('after Lazy2');
const res = yield doNow();
console.log('after now');
return res;
})
// doAsync();
//打印出:
// start
// do Lazy1
// after Lazy1
// do Lazy2
// after Lazy2
// do now!
// after now
// 表达式输出为
// "now"
//babel插件思路
function transportAsyncFunction({ types }) {
return {
visitor: {
FunctionDeclaration(path) {
if (path.node.async === true) {
path.node.async === false;
path.node.generator === true;
}
//遍历函数内容
path.traverse({AwaitExpression(pathAwait){
//替换AwaitExpression节点为YieldExpression
pathAwait.node.type = 'YieldExpression';
}})
//把节点转换为CallExpression
//创建runGenerator 把节点转换为CallExpression并把上一步得到的节点当作param
//替换上一步得到的节点
types.replaceWith()
}
}
}
}
//Function构造函数思路
fucntion(target){
//匹配async关键字
const regAsync = //s*async[^{}\(]{1,}(?=function|\()/;
//匹配await关键字
const regAwait = /(?<=[/s]+)(await)(?=[/s]+)/g;
const regBody = /(? let funcStr = target.toString();
let resultStr = null;
resultStr = funcStr.replace(regAsync,' * ');
//如果是箭头函数需要转换成普通函数
resultStr = funcStr.replace(/\(([/w]+)\)[/s]*=>/,'function($0)');
//提取参数
const params = funcStr.replace(/\(([/w]*)\)/,'$0').split(',');
resultStr = funcStr.replace(regAwait,' yield ');
const body = resultStr.replace(regBody,'$1');
//构造出函数
const resultFunction = new Function(...params,body);
return runGenerator(resultFunction());
}

推荐阅读
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 本文讨论了编写可保护的代码的重要性,包括提高代码的可读性、可调试性和直观性。同时介绍了优化代码的方法,如代码格式化、解释函数和提炼函数等。还提到了一些常见的坏代码味道,如不规范的命名、重复代码、过长的函数和参数列表等。最后,介绍了如何处理数据泥团和进行函数重构,以提高代码质量和可维护性。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
author-avatar
木色雪魂K
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有