参考极客时间浏览器工作原理与实战
// 定义了一个promise
function getNum(num) {
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(num+1)
},0)
})
}
// 重点 自动执行器
function asyncFun(func) {
var gen = func();
function next(data) {
var result = gen.next(data);
if (result.done) return result.value;
result.value.then(function(data) {
next(data); // 递归调用
})
}
next();
}
var func = function* (){
var f1 = yield getNum(1);
var f2 = yield getNum(f1);
console.log(f2);
}
image.png
图中可以看出来协程的四点规则:
1、通过调用生成器函数 genDemo 来创建一个协程 gen,创建之后,gen 协程并没有立即执行。
2、要让 gen 协程执行,需要通过调用 gen.next。
3、当协程正在执行的时候,可以通过 yield 关键字来暂停 gen 协程的执行,并返回主要信息给父协程。
4、如果协程在执行期间,遇到了 return 关键字,那么 JavaScript 引擎会结束当前协程,并将 return 后面的内容返回给父协程。
生成器就是协程的一种实现方式
//foo函数
function* foo() {
let response1 = yield fetch('https://www.geekbang.org')
console.log('response1')
console.log(response1)
let response2 = yield fetch('https://www.geekbang.org/test')
console.log('response2')
console.log(response2)
}
//执行foo函数的代码
let gen = foo()
function getGenPromise(gen) {
return gen.next().value
}
getGenPromise(gen).then((response) => {
console.log('response1')
console.log(response)
return getGenPromise(gen)
}).then((response) => {
console.log('response2')
console.log(response)
})
以上就是协程和 Promise 相互配合执行的一个大致流程。不过通常,我们把执行生成器的代码封装成一个函数,并把这个执行生成器代码的函数称为执行器(可参考著名的 co 框架),如下面这种方式:
网友评论