js下写一个事件队列操作函数


Posted in Javascript onJuly 19, 2010

前两天在网上看到这一系列的文章《写一个JavaScript异步调用框架1,2,3,4,5,6》。

异步操作可能会产生你不希望的事件触发顺序。这个问题以前也遇到过,当时没想太多,也就是直接多层嵌套(在ajax返回以后嵌套下一个事件)来解决。

认真的看了一遍。看的头昏,不得不说我可能基础并不好,在大局上的掌握也不好。d反正我是觉得很难理解,也不觉得它的调用时够方便的。

 如果是这么调用:

var chain = Async.go(0);
chain
.next(function(){setTimeout("alert(1)",3000)})
.next(function(){setTimeout("alert(2)",3000)})
.next(function(){setTimeout("alert(3)",3000)});

我觉得这样是完美的。但是实际上如果是异步调用却是要这样:

var chain = Async.go(0);
chain.next(function(){
var operation = new Async.Operation();
setTimeout(function(){ operation.yield("hello"); }, 3000);
return operation;
});

当然最后一篇提到再次封装一下,我想大致上就能解决这种不方便的调用了。

其实以前我也是有过这个念头,就是找一个能按我的顺序来触发的类或者什么,群里问问是否有这种类的时候,别人总都回句,在onreadychange里执行就好啦,甚至有嘲笑的!加上当时又是初学的菜鸟也便作罢了。而现在虽然依旧是菜鸟,但终究飞了一段路程了。就试试按自己的理解写一个事件队列吧。

我总习惯看代码说话,所以先上代码,然后说一下思路好了:

/** 
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试了一下恩,看来还是没问题的。

Javascript 相关文章推荐
javascript延时重复执行函数 lLoopRun.js
Jun 29 Javascript
一个基于jQuery的树型插件(OrangeTree)使用介绍
May 03 Javascript
JavaScript改变HTML元素的样式改变CSS及元素属性
Nov 12 Javascript
判断在css加载完毕后执行后续代码示例
Sep 03 Javascript
推荐一个自己用的封装好的javascript插件
Jan 29 Javascript
莱鸟介绍window.print()方法
Jan 06 Javascript
AngularJS指令中的绑定策略实例分析
Dec 14 Javascript
浅析BootStrap中Modal(模态框)使用心得
Dec 24 Javascript
JavaScript简单拖拽效果(1)
May 17 Javascript
vue项目优化之通过keep-alive数据缓存的方法
Dec 11 Javascript
vue+element搭建后台小总结 el-dropdown下拉功能
Apr 10 Javascript
使用vue重构资讯页面的实例代码解析
Nov 26 Javascript
js+css在交互上的应用
Jul 18 #Javascript
基于jQuery试卷自动排版系统
Jul 18 #Javascript
Date对象格式化函数代码
Jul 17 #Javascript
js下利用控制器载入对应脚本
Jul 17 #Javascript
js 纯数字不重复排列的另类方法
Jul 17 #Javascript
jQuery Autocomplete自动完成插件
Jul 17 #Javascript
一个js拖拽的效果类和dom-drag.js浅析
Jul 17 #Javascript
You might like
过滤掉PHP数组中的重复值的实现代码
2011/07/17 PHP
PHP版国家代码、缩写查询函数代码
2011/08/14 PHP
PHP设计模式之适配器模式代码实例
2015/05/11 PHP
php session的锁和并发
2016/01/22 PHP
PHP判断一个数组是另一个数组子集的方法详解
2017/07/31 PHP
PHP For循环字母A-Z当超过26个字母时输出AA,AB,AC
2020/02/16 PHP
通过JS 获取Mouse Position(鼠标坐标)的代码
2009/09/21 Javascript
jQuery html() in Firefox (uses .innerHTML) ignores DOM changes
2010/03/05 Javascript
JavaScript 原型继承
2011/12/26 Javascript
自己做的模拟模态对话框实现代码
2012/05/23 Javascript
node.js中的fs.lstat方法使用说明
2014/12/16 Javascript
基于d3.js实现实时刷新的折线图
2016/08/03 Javascript
AngularJS 服务详细讲解及示例代码
2016/08/17 Javascript
js获取当前时间(昨天、今天、明天)
2016/11/23 Javascript
jquery封装插件时匿名函数形参和实参的写法解释
2017/02/14 Javascript
javascript实现数据双向绑定的三种方式小结
2017/03/09 Javascript
Javascript实现从小到大的数组转换成二叉搜索树
2017/06/13 Javascript
详解nodejs实现本地上传图片并预览功能(express4.0+)
2017/06/28 NodeJs
Bootstrap导航菜单点击后无法自动添加active的处理方法
2018/08/10 Javascript
详解Nodejs get获取远程服务器接口数据
2019/03/26 NodeJs
jQuery中DOM常见操作实例小结
2019/08/01 jQuery
微信小程序页面滚动到指定位置代码实例
2019/09/07 Javascript
JavaScript生成随机验证码代码实例
2019/09/28 Javascript
Python实现股市信息下载的方法
2015/06/15 Python
python正则表达式之对号入座篇
2018/07/24 Python
python+django+rest框架配置创建方法
2019/08/31 Python
Python模块 _winreg操作注册表
2020/02/05 Python
Python参数传递实现过程及原理详解
2020/05/14 Python
python两个list[]相加的实现方法
2020/09/23 Python
python实现移动木板小游戏
2020/10/09 Python
俄罗斯披萨、寿司和面食送货到家服务:2 Берега
2019/12/15 全球购物
带病坚持工作事迹
2014/05/03 职场文书
求职自荐信怎么写
2015/03/04 职场文书
运动会闭幕式致辞
2015/07/29 职场文书
小学班主任工作经验交流材料
2015/11/02 职场文书
NASA 机智号火星直升机拍到了毅力号设备碎片
2022/04/29 数码科技