原文:https://segmentfault.com/a/1190000018938853
参考理解:
https://es6.ruanyifeng.com/#docs/iterator
https://blog.csdn.net/ixygj197875/article/details/79199181
按照序数写在备注上边了
let genRun = function() {
function run(p, gen) {
//5.第一个promise执行.then
p.then(
resolve => {
p = gen.next(resolve).value; //6.对于遍历器的第二个promise传入resolve的值,next()方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值
if (p !== undefined) { //7.如果下一个p存在,执行下一个run(迭代)
run(p, gen)
}
},
reject => {
// p = gen.throw(reject).value;//加上这句是遇到错误就不会进行next
p = gen.next(reject).value; //8.对于遍历器的第二个promise传入reject的值
if (p !== undefined) {
run(p, gen)
}
})
}
//2.返回的是函数体,传的参数是function*{...}
return function(generator) {
let g = generator(); //3.第一个yield
run(g.next().value, g) //4.传参遍历器的第一个promise值和该遍历器,转到run函数体。传递的value为resolve(num * 100)或reject(num + " request err")
}
}();
function request() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
let num = Math.random();
if (num > 0.8) {
reject(num + " request err");
} else {
resolve(num * 100);
}
}, 100)
})
}
genRun(
function*() { //匿名的遍历器函数
try {
let response1 = yield request();
// 1.第一个next取到这个request返回的Promise并立即执行
//9.接收上一个.next(resolve)、.next(reject)或.throw(reject)里面的参数作为返回值
console.log("response1", response1);
let response2 = yield request(); //
console.log("response2", response2);
let response3 = yield request(); //
console.log("response3", response3);
//...也可以yield其他promise对象
} catch (e) {
console.error(e)
}
});