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 相关文章推荐
基于Jquery的$.cookie()实现跨越页面tabs导航实现代码
Mar 03 Javascript
JQUERY 设置SELECT选中项代码
Feb 07 Javascript
jQuery中$.click()无效问题分析
Jan 29 Javascript
浅谈JavaScript中运算符的优先级
Jul 07 Javascript
js+css实现的圆角边框TAB选项卡滑动门代码分享(2款)
Aug 26 Javascript
Ionic实现页面下拉刷新(ion-refresher)功能代码
Jun 03 Javascript
移动端基础事件总结与应用
Jan 12 Javascript
纯JavaScript实现实时反馈系统时间
Oct 26 Javascript
JavaScript对象的浅拷贝与深拷贝实例分析
Jul 25 Javascript
jQuery插件实现非常实用的tab栏切换功能【案例】
Feb 18 jQuery
微信小程序实现点击空白隐藏的方法示例
Aug 13 Javascript
解决angular 使用原生拖拽页面卡顿及表单控件输入延迟问题
Apr 21 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
《猛禽小队》:DC宇宙的又一超级大烂片
2020/04/09 欧美动漫
PHP读MYSQL中文乱码的快速解决方法
2016/10/01 PHP
PHP用mysql_insert_id()函数获得刚插入数据或当前发布文章的ID
2016/11/25 PHP
javascript EXCEL 操作类代码
2009/07/30 Javascript
js实现点击注册按钮开始读秒倒计时的小例子
2013/05/11 Javascript
Jquery使用val方法读写value值
2015/05/18 Javascript
JS实现常见的TAB、弹出层效果(TAB标签,斑马线,遮罩层等)
2015/10/08 Javascript
字符串反转_JavaScript
2016/04/28 Javascript
使用jQuery Rotare实现微信大转盘抽奖功能
2016/06/20 Javascript
js实现浏览器倒计时跳转页面效果
2016/08/12 Javascript
jquery中用函数来设置css样式
2016/12/22 Javascript
angular select 默认值设置方法
2017/06/23 Javascript
使用JavaScript中的lodash编写双色球效果
2018/06/24 Javascript
vue form check 表单验证的实现代码
2018/12/09 Javascript
vue2配置scss的方法步骤
2019/06/06 Javascript
Vue 实现监听窗口关闭事件,并在窗口关闭前发送请求
2020/09/01 Javascript
Python 文件操作技巧(File operation) 实例代码分析
2008/08/11 Python
使用Python来编写HTTP服务器的超级指南
2016/02/18 Python
Python两个内置函数 locals 和globals(学习笔记)
2016/08/28 Python
Python用户推荐系统曼哈顿算法实现完整代码
2017/12/01 Python
python cumsum函数的具体使用
2019/07/29 Python
tensorflow 实现自定义layer并添加到计算图中
2020/02/04 Python
css3实现图片遮罩效果鼠标hover以后出现文字
2013/11/05 HTML / CSS
Mountain Warehouse澳大利亚官网:欧洲家庭户外品牌倡导者
2016/11/20 全球购物
Oral-B荷兰:牙医最推荐的品牌
2020/02/25 全球购物
迪卡侬(Decathlon)加拿大官网:源自法国的运动专业超市
2020/11/22 全球购物
会计系毕业个人自荐信格式
2013/09/23 职场文书
加拿大留学自荐信
2014/01/28 职场文书
烹调加工管理制度
2014/02/04 职场文书
企业标语大全
2014/07/01 职场文书
社区创先争优承诺书
2014/08/30 职场文书
军人离婚协议书样本
2014/10/21 职场文书
思想品德评语大全
2014/12/31 职场文书
幼儿园园长新年寄语
2015/08/17 职场文书
《只有一个地球》教学反思
2016/02/16 职场文书
最新动漫情报:2022年7月新番定档超过30部, OVERLORD骨王第四季也在其中噢
2022/05/04 日漫