时间:2021-07-01 10:21:17 帮助过:9人阅读
/**
KEQueue —— Events Queue
@Author ake by 2010-04-25
http://www.cnblogs.com/akecn
@param data 事件队列中每个事件都会将该参数作为第一个参数传递下去,除非通过KEQueue.status修改它的值。
@method next(Function) 下一个要执行的事件。
@method wait(Number) 等待一定时间后执行下一个事件。
@method sleep() 停止事件序列的执行。
@method wake() 继续执行事件序列。
**/
var KEQueue = function(data) {
this.staticQueue = [];
this.asyncQueue = [];
this.status = "running";
this.result = data;
return this;
}
KEQueue.prototype = {
next:function(callback, async) {//添加一个方法
if(!!async) {
this.staticQueue.push("async");//如果是异步方法(会有延时效果的方法)就添加标识
this.asyncQueue.push(callback);//延时方法的存放数组
}else {
this.staticQueue.push(callback);//直接触发的方法的存放数组
}
return this;
},
wait:function(delay) {//延迟执行序列
var self = this;
this.next(function() {//模拟添加一个延时方法
setTimeout(function() {
self.wake.call(self)
}, delay);
},true);
return this;
},
go:function() {//按事件添加的先后顺序依次执行事件
if(this.staticQueue.length == 0) return;
while(this.staticQueue.length > 0) {
if(this.status === "sleep") return;
var fun = this.staticQueue.shift();
if(typeof fun == "string" && fun == "async") {
fun = this.asyncQueue.shift();
fun(this.result);
this.sleep();
}else {
fun(this.result);
}
}
},
sleep:function() {
this.status = "sleep";
},
wake:function() {
this.status = "running";
this.go();
}
}
估计你看了代码就已经明白是怎么做的了,代码也很简单。
其实就是循环去执行一个数组中的方法,如果数组中存放的不是function,就停止队列的操作直到被叫醒(wake())。使用方法也比较偏向我喜欢的方式。
当然也许我只是看到事件是按我添加的顺序去执行了,但有很多其他的情况或者原因没想到。如果您有建议或者意见,欢迎留言!
以下是使用示例。
代码如下:
//示例1 添加事件、执行事件队列
function show(n) {
console.log(n);
}
var o = new KEQueue("0");
o.next(function(d) { //参数是构造时传递的数据。整个事件队列都会返回该数据作为参数。
show(d + 1);
}).next(function(d) {
setTimeout(function() { //模拟延时操作(异步操作)
show(d + 2);
o.result = 0; //更改用以传递的数据,如果不修改,该数据会保持一致一直传递到最后一个事件。
o.wake(); //需要手动唤醒序列
},2000);
},true).next(function(d){
show(d + 3);
}).go();
o.next(function(d) {
setTimeout(function() {show(d + 4);o.wake(); },1000);
},true).wait(1000) //手动推迟1秒执行下面的方法
.next(function(d) {
show(d + 5);
}).go();
//示例2
o.next(function() {
show(1);
})
setTimeout(function() {
o.next(function(){
setTimeout(function() {
show(2);
o.wake();
},2000)
},true).go();
},1000);
setTimeout(function() {
o.next(function() {
show(3);
}).go();
},2000);
PS:晚上睡觉的时候突然想说如果添加的是一个复杂事件,那么所消耗的时间久长了,这样会不会造成不期望的事件顺序呢?如果这样每个事件最后都要显示当做异步事件去处理,那这个队列就没什么大的意义了,最多就是帮你梳理一下事件顺序,仅此而已了。。
早上去公司路上又突然想起,JavaScript是单线程操作的哎,事件会被阻塞的,如果是多线程,估计也不需要做这么个队列了。
刚才写个demo试了一下恩,看来还是没问题的。