参考链接:https://juejin.im/post/5e79e841f265da5726612b6e
1. 准备异步函数
// 异步函数
const getData = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve('data...');
}, 1000);
})
}
2. 写代码时async-await的例子
async function test () {
const data = await getData()
console.log('data: ', data);
const data2 = await getData()
console.log('data2: ', data2);
return 'success'
}
// async相当于将函数包装上Promise
test().then(res => console.log(res))
3. 众所周知,async-await是生成器的语法糖,因此,需要封装一个async2Generator函数
const test = async2Generator(
function* test () {
const data = yield getData();
console.log('data: ', data);
const data2 = yield getData();
console.log('data2: ', data2);
return 'success';
}
);
4. async2Generator函数的推导步骤,举个栗子:
function* test1 () {
const data = yield getData();
console.log('data: ', data);
const data2 = yield getData();
console.log('data2: ', data2);
return 'success'
}
const g = test1();
const dataPromise = g.next();
dataPromise.value.then((value1) => { // 这里注意是.value.then,因为返回值.value才是Promise
console.log(value1);
const dataPromise2 = g.next(value1);
dataPromise2.value.then((value2) => {
console.log(value2);
g.next(value2);
})
});
5. async2Generator函数的递归实现
function async2Generator (generatorFunc) {
return function () {
const gen = generatorFunc.apply(this, arguments);// arguments一般为空
return new Promise((resolve, reject) => {
function step (key, args) {
let result;
try {
result = gen[key](args);
} catch (err) {
return reject(err);
}
const { value, done } = result; // 生成器返回的对象有两个值, done判断是否结束
if (done) {
return resolve(value);
} else {
return Promise.resolve(value) // 包装成Promise
.then((value) => {
step('next', value);
}, (err) => {
step('throw', err);
});
}
}
step('next'); // 生成器的第一个步骤 gen.next(), 无需传值
});
}
}