作者:木色雪魂K | 来源:互联网 | 2023-09-18 14:45
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());
}