用自定义iterator实现异步流程控制
Object.prototype[Symbol.iterator]为对象添加Symbol.iterator属性,即生成器迭代函数
asyncRunControl用来控制异步执行流程,一般来说
迭代器函数执行之后,一步一步调用next()方法可以获取每一步执行的·结果,但是如果其中的一步需要异步执行,需要等待的时候,使用next便无法控制,next原生只能控制同步执行,不能等待异步执行结果。
asyncRunControl是用来控制每一步执行步骤的全部完成,可以是同步结果或者异步结果,最后都会等待最终结果出来之后,才会进行下一步的next执行。
let arr = {
name: "sunshine",
age: 23,
sex: "女"
}
Object.prototype[Symbol.iterator] = function () {
var ref = this;
let index = 0;
let keys = Object.keys(ref);
return {
next: function () {
key = keys[index];
value = ref[key];
let v = value;
if (key === "age") {
value = new Promise(resolve => {
setTimeout(function () {
resolve(v);
}, 300)
})
}
return {
value: value,
done: index++ >= keys.length
}
}
}
}
function asyncRunControl(iterator) {
var it = iterator.next();
let value = it.value;
let done = it.done;
if (!done) {
if (value instanceof Promise) {
value.then(data => {
console.log(data);
asyncRunControl(iterator)
})
} else {
console.log(value);
asyncRunControl(iterator)
}
}
}
var it = arr[Symbol.iterator]();
asyncRunControl(it);
generator
function* myGen(){
yield "1";
yield "2";
yield "3";
yield "4";
return "last"
}
var gener=myGen();
console.log(gener.next());
console.log(gener.next());
但是generator虽然可以帮我们自动生成生成器函数,但是问题是还是不能帮我们处理异步执行流程。
异步的promise并不会帮我们执行,而是直接返回一个Promise对象。
function* myGen(){
yield "sunshine"
yield new Promise((resolve) => {
setTimeout(function(){
resolve("age")
},3000)
})
yield "sex";
}
let gen=myGen();
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
手动处理生成函数的异步处理流程
function* myGen(){
yield "sunshine"
yield new Promise((resolve) => {
setTimeout(function(){
resolve("age")
},3000)
})
yield "sex";
}
let gen=myGen();
asyncRunControl(gen);
function asyncRunControl(iterator) {
var it = iterator.next();
let value = it.value;
let done = it.done;
if (!done) {
if (value instanceof Promise) {
value.then(data => {
console.log(data);
asyncRunControl(iterator)
})
} else {
console.log(value);
asyncRunControl(iterator)
}
}
}
async/await
async function iteratorFun(){
console.log("sunshine");
let x=await new Promise((resolve) => {
setTimeout(function(){
resolve("age")
},3000)
})
console.log(x);
console.log("sex")
}
iteratorFun();