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 实现的点击复制代码
Mar 24 Javascript
jquery实现文本框鼠标右击无效以及不能输入的代码
Nov 05 Javascript
js控制表单操作的常用代码小结
Aug 15 Javascript
JS实现当前页居中分页效果的方法
Jun 18 Javascript
JavaScript中Date对象的常用方法示例
Oct 24 Javascript
javascript针对cookie的基本操作实例详解
Nov 30 Javascript
JS实现字符串转日期并比较大小实例分析
Dec 09 Javascript
基于Vue实现图书管理功能
Oct 17 Javascript
jQuery zTree搜索-关键字查询 递归无限层功能实现代码
Jan 25 jQuery
React Native开发封装Toast与加载Loading组件示例
Sep 08 Javascript
jqGrid表格底部汇总、合计行footerrow处理
Aug 21 Javascript
详解vue3.0 的 Composition API 的一种使用方法
Oct 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+Html+缓存
2006/12/20 PHP
无法在发生错误时创建会话,请检查 PHP 或网站服务器日志,并正确配置 PHP 安装最快的解决办法
2010/08/01 PHP
PHP实现利用MySQL保存session的方法
2014/08/23 PHP
php导入excel文件到mysql数据库的方法
2015/01/14 PHP
php返回字符串中所有单词的方法
2015/03/09 PHP
php文件上传的两种实现方法
2016/04/04 PHP
php+redis消息队列实现抢购功能
2018/02/08 PHP
php微信公众号开发之现金红包
2018/04/16 PHP
javascript之锁定表格栏位
2007/06/29 Javascript
基于JQuery的浮动DIV显示提示信息并自动隐藏
2011/02/11 Javascript
JS实现光滑展开合拢的菜单效果代码
2015/09/16 Javascript
checkbox 选中一个另一个checkbox也会选中的实现代码
2016/07/09 Javascript
JS如何生成一个不重复的ID的函数
2016/12/25 Javascript
利用C/C++编写node.js原生模块的方法教程
2017/07/07 Javascript
Kindeditor单独调用多图上传实例
2017/07/31 Javascript
vue父组件向子组件(props)传递数据的方法
2018/01/02 Javascript
node实现基于token的身份验证
2018/04/09 Javascript
vue将单页面改造成多页面应用的方法
2018/11/25 Javascript
layui的layedit富文本赋值方法
2019/09/18 Javascript
vue图片上传组件使用详解
2019/12/23 Javascript
vue+elementUi 实现密码显示/隐藏+小图标变化功能
2020/01/18 Javascript
JavaScript canvas动画实现时钟效果
2020/02/10 Javascript
vue实现购物车列表
2020/06/30 Javascript
[01:03]悬念揭晓 11月26日DOTA2完美盛典不见不散
2017/11/23 DOTA
Python文本处理之按行处理大文件的方法
2018/04/09 Python
python针对不定分隔符切割提取字符串的方法
2018/10/26 Python
python卸载后再次安装遇到的问题解决
2019/07/10 Python
Python FTP文件定时自动下载实现过程解析
2019/11/12 Python
python默认参数调用方法解析
2020/02/09 Python
python关于变量名的基础知识点
2020/03/03 Python
Java面试中常遇到的问题,也是需要注意的几点
2013/08/30 面试题
广告业务员岗位职责
2014/02/06 职场文书
行政部工作岗位职责范本
2014/03/05 职场文书
天猫活动策划方案
2014/08/21 职场文书
简易版租房协议书范本
2014/10/13 职场文书
alibaba seata服务端具体实现
2022/02/24 Java/Android