第一步
function* test() {
var a = 1;
yield a;
let b = 2;
return a
}
function splitIterator(fx) {
let code = fx.toString().match(/{(.|\s)*}/g)[0].slice(1, -1);
let variable = code.match(/let(\s*).|var(\s*).|const(\s*).*/g).join(";");
let rmCodeVeriable = code.replace(/let|var|const/g, '');
let mainCode = rmCodeVeriable.match(/(.|\s)*?(yield|return).*/g).map(v => v.replace(/yield/g, "return"))
const codeTranslate = mainCode.map((v, i) => {
return `
case ${i}:
context.next = ${i+1}
context.done = ${i+1 >= mainCode.length ? 'true' : 'false'}
${
v
}
`
})
const excuteFx = `
var fx = function (){
while(1){
switch(context.per = context.next){
${codeTranslate.join("")}
default:
context.done = true
context.value = undefined
return;
}
}
}
`
return {
variable,
excuteFx
}
}
function Generator(test, fxString) {
const {
variable,
excuteFx
} = splitIterator(test)
const context = {
per: 0,
next: 0,
done: false,
value: undefined
}
eval(variable)
eval(fxString || excuteFx)
return {
next: function(paramters) {
return {
value: fx(paramters),
done: context.done,
}
}
}
}
var a = Generator(test)
console.log(a.next())
console.log(a.next())
console.log(a.next())
第二步
async function testTemple() {
var content = await fetch("https://juejin.cn/post/6844903929369591822");
console.log(await content.text())
return content
}
function executeAsyncFX(iterator) {
var gen = iterator || (function* asyncFxAsGenator() {
var content = yield fetch(
"http://127.0.0.1:8848/note/%E5%89%8D%E7%AB%AF/%E6%89%8B%E5%86%99/Generator.html");
console.log("2222")
console.log(yield content.text())
return content
})();
(function(value) {
const results = gen.next(value);
Promise.resolve(results.value).then(
(v) => {
if (!results.done) {
console.log(v)
arguments.callee(v)
}
}
);
})()
}
executeAsyncFX()
第三步
var gen = function* asyncFxAsGenator() {
var content = yield fetch("http://127.0.0.1:8848/note/%E5%89%8D%E7%AB%AF/%E6%89%8B%E5%86%99/Generator.html");
console.log("2222")
console.log(yield content.text())
return content
}
var iterator = Generator(gen, `var fx = function (paramters){
while(1){
switch(context.per = context.next){
case 0:
context.next = 1
context.done = false
return fetch("http://127.0.0.1:8848/note/%E5%89%8D%E7%AB%AF/%E6%89%8B%E5%86%99/Generator.html");
case 1:
content = paramters
context.next = 2
context.done = false
console.log("2222")
return content.text()
case 2:
context.next = 3
context.done = true
return content
default:
context.done = true
context.value = undefined
return;
}
}
}`)
executeAsyncFX(iterator)
总结:aync函数手写实现
- 可以通过一个自动执行的generator实现,实际内部也依靠Promise.resolve,then 回调函数递归实现。
- 也可以通过babel直接将await后面表达式转成Promise.resolve在then回调里面执行余下直到下一个await的代码,也就是回调地域。
- 也就是说async的实现实际上依赖的是promise。