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与DropDownList 区别分析
Jan 01 Javascript
ExtJs grid行 右键菜单的两种方法
Jun 19 Javascript
jquery判断元素的子元素是否存在的示例代码
Feb 04 Javascript
jQuery中选择器小问题(新人难免遇到)
Mar 31 Javascript
javascript常用函数(2)
Nov 05 Javascript
jquery自定义插件——window的实现【示例代码】
May 06 Javascript
动态加载css方法实现和深入解析
Jan 18 Javascript
80%应聘者都不及格的JS面试题
Mar 21 Javascript
JS简单实现自定义右键菜单实例
May 31 Javascript
vue教程之toast弹框全局调用示例详解
Aug 24 Javascript
vue实现标签云效果的方法详解
Aug 28 Javascript
Vue3如何理解ref toRef和toRefs的区别
Feb 18 Vue.js
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
Amazon Prime Video平台《无限住人 -IMMORTAL-》2020年开始TV放送!
2020/03/06 日漫
php 运行效率总结(提示程序速度)
2009/11/26 PHP
php通过文件头检测文件类型通用代码类(zip,rar等)
2010/10/19 PHP
深入分析php之面向对象
2013/05/15 PHP
IIS6.0 开启Gzip方法及PHP Gzip函数分享
2014/06/08 PHP
在win系统安装配置 Memcached for PHP 5.3 图文教程
2015/03/03 PHP
php生成毫秒时间戳的实例讲解
2017/09/22 PHP
php ajax数据传输和响应方法
2018/08/21 PHP
php设计模式之组合模式实例详解【星际争霸游戏案例】
2020/03/27 PHP
JavaScript中把数字转换为字符串的程序代码
2013/06/19 Javascript
常规表格多表头查询示例
2014/02/21 Javascript
node.js+express制作网页计算器
2016/01/17 Javascript
JavaScript实现打地鼠小游戏
2020/04/23 Javascript
weex里Vuex state使用storage持久化详解
2017/09/09 Javascript
Electron 如何调用本地模块的方法
2019/02/01 Javascript
JQuery常用简单动画操作方法回顾与总结
2019/12/07 jQuery
jquery html添加元素/删除元素操作实例详解
2020/05/20 jQuery
跟老齐学Python之不要红头文件(2)
2014/09/28 Python
详解python使用Nginx和uWSGI来运行Python应用
2018/01/09 Python
python如何给字典的键对应的值为字典项的字典赋值
2019/07/05 Python
使用python画社交网络图实例代码
2019/07/10 Python
python原类、类的创建过程与方法详解
2019/07/19 Python
使用Python爬虫库requests发送请求、传递URL参数、定制headers
2020/01/25 Python
Python networkx包的实现
2020/02/14 Python
Python图像处理库PIL中图像格式转换的实现
2020/02/26 Python
基于python实现图片转字符画代码实例
2020/09/04 Python
html5 datalist 选中option选项后的触发事件
2020/03/05 HTML / CSS
哈利波特商店:Harry Potter Shop
2018/11/30 全球购物
销售总监岗位职责
2014/01/04 职场文书
十八大闭幕感言
2014/01/22 职场文书
实习评语大全
2014/04/26 职场文书
师德模范事迹材料
2014/06/03 职场文书
校园文化标语
2014/06/18 职场文书
省委召开党的群众路线教育实践活动总结大会报告
2014/10/21 职场文书
2015年党建工作汇报材料
2015/06/25 职场文书
2016年大学生党员公开承诺书
2016/03/24 职场文书