原文: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)
}
});