写一个 异步事件顺序执行器
发布于 6 小时前 作者 DoubleCG 89 次浏览 最后一次编辑是 几秒前 来自 分享

第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);
	}
]);

待续

回到顶部