写一个 异步事件顺序执行器
第1步
理解promise,这里为了减少不必要的干扰,仅传入resolve。
let p1 = new Promise((resolve)=>{
resolve(1);
});
p1.then(console.log);
let p2 = new Promise((resolve)=>{
resolve(1);
});
p2.then( (i)=>{
console.log(100*i)
});
第二步:
理解 promise对代码可读性的优化
new Promise((resolve)=>{
let e = 1;
resolve(e);
}).then(
(e)=>{
return new Promise((resolve)=>{
console.log(e);
resolve(e+1);
});
}).then(
(e)=>{
return new Promise((resolve)=>{
console.log(e);
resolve(e+1);
});
}).then(console.log);
第三步
代码抽象,得到主流程十分精简且可读性高的代码。
function promiseCount(e){
return new Promise((resolve)=>{
console.log(e);
resolve(e+1);
});
}
new Promise((resolve)=>{
resolve(1);
}).then(
promiseCount
).then(
promiseCount
).then(console.log);
第四步
编写管理器,把setTimeout作为测试用异步事件。管理器内部设置index作 “辅助指针” 指向当前递归中的事件。
let eventArray = [
(callback)=>{
console.log(1);
$.ajax({
url,
success(){
callback();
}
})
},
(callback)=>{
console.log(2);
setTimeout(callback,100);
},
(callback)=>{
console.log(3);
setTimeout(callback,100);
},
(callback)=>{
console.log(4);
setTimeout(callback,100);
},
(callback)=>{
console.log(5);
setTimeout(callback,100);
}
];
function eventManager(eventArray){
let index = -1;
(function lambda(){
return new Promise((resolve)=>{
index ++; // 指向队列中的下一个事件
if(index<eventArray.length){
eventArray[index](resolve); // 把resolve交由当前事件的回调函数处理,即当前事件执行完之后就会执行then中新的lambda,得到的效果是“同步”
}
}).then(lambda);
})();
}
eventManager(eventArray);
第五步
增加数据收集器
let eventArray = [
(callback)=>{
console.log(1);
setTimeout(function(){
callback().collector.z=0;
callback().resolve();
},100);
},
(callback)=>{
console.log(2);
setTimeout(function(){
callback().collector.a=1;
callback().resolve();
},100);
},
(callback)=>{
console.log(3);
setTimeout(function(){
callback().collector.b=2;
callback().resolve();
},100);
},
(callback)=>{
console.log(4);
setTimeout(function(){
callback().collector.c=3;
callback().resolve();
},100);
},
(callback)=>{
console.log(5);
setTimeout(function(){
callback().collector.d=4;
callback().resolve();
},100);
}
];
let EventManager = function(eventArray){
let index = -1, events = eventArray;
let collector = {};
(function lambda(){
return new Promise((resolve)=>{
index ++;
if(index<events.length){
events[index](()=>{
return {
resolve,
collector,
}
});
}
}).then(lambda);
})();
this.getData = function(){
return collector;
}
this.clear = function(){
collector = null;
}
}
let ev = new EventManager(eventArray);
setTimeout(function(){
console.log(ev.getData())
},2000);
collector会一直存在ev对象的内部,仅能通过调用getData获取。当然还可以往EventManager里添加更多方法。
第六步
提炼核心, 并把 resolve 改为 next.
let EventManager = function(eventArray){
let index = -1;
(function lambda(){
return new Promise((next)=>{
index ++;
if(index<eventArray.length){
eventArray[index](next);
}
}).then(lambda);
})();
}
EventManager([
(next)=>{
setTimeout(()=>{
// do something
console.log(1);
next();
},100);
},
(next)=>{
setTimeout(()=>{
// do something
console.log(2);
next();
},100);
},
(next)=>{
setTimeout(()=>{
// do something
console.log(3);
next();
},100);
},
(next)=>{
setTimeout(()=>{
// do something
console.log(4);
next();
},100);
},
(next)=>{
setTimeout(()=>{
// do something
console.log(5);
next();
},100);
}
]);
待续