定义生成器
generator生成器函数的*
模拟async,yield模拟await
function* gener() {
let result = yield Promise.resolve("async await");
console.log("result ", result);
}
如果我们将yield当成我们常用的await,那么result返回的应该是promise的结果;
执行生成器
let gen = gener();
let firstExec = gen.next();
console.log(firstExec.value, firstExec.done); // Promise false
通过调用next方法拿到yield后面的结果{ value:promise, done:false }
,生成器gener方法内部打印result需要再次调用next方法,将第一次的value传给next方法,这个参数会作为yield的返回值。
let secExec = gen.next(firstExec.value);
// done为true表示调用结束
console.log(secExec.value, secExec.done); // undefined true
result打印promise。也可以next直接传promise的结果,await用法就是这样。
函数封装调用
通过函数封装调用代码,编写生成器的执行器:
function execGener(gener) {
let gen = gener();
let firstExec = gen.next();
firstExec.value.then((res) => {
gen.next(res);
});
}
// 执行生成器
execGener(gener); // result async await
上面只能处理一次yield ,下面情况无法处理,因为上面只调了两次next。
function* gener() {
let result = yield Promise.resolve("async await");
let result1 = yield Promise.resolve("async await1");
console.log("result ", result);
console.log("result ", result1);
}
加强方法
递归调用next,直到yield执行完毕,next的done返回true表示生成器执行完毕。
function execGener(gener) {
let gen = gener();
function next(data) {
let result = gen.next(data);
if (result.done) return; // 递归出口,出口之前还会调一次next,是为了把数据给上一个yeild结果,因为第二次next之后才能给yield结果赋值。
result.value.then((res) => {
next(res);
});
}
next();
}
// 执行生成器
execGener(gener);
执行流程解析:
- 第一次调gen.next,返回值value拿到第一个promise;
- 第二次调gen.next,传参第一个promise的结果,于是result被赋值为第一个promise,随后执行第二个yield,返回值value拿到第二个promise;
- 第三次调gen.next,传参第二个promise的结果给result1赋值,执行结束。
1
1
1
1
1
1
1
1
1
1