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引用指针使用介绍
Nov 07 Javascript
Javascript算符的优先级介绍
Mar 20 Javascript
js实现TAB切换对应不同颜色的代码
Aug 31 Javascript
AngularJs Understanding the Controller Component
Sep 02 Javascript
微信小程序 购物车简单实例
Oct 24 Javascript
javascript设计模式之Adapter模式【适配器模式】实现方法示例
Jan 13 Javascript
vue.js数据绑定的方法(单向、双向和一次性绑定)
Jul 13 Javascript
浅谈ES6新增的数组方法和对象
Aug 08 Javascript
js canvas画布实现高斯模糊效果
Nov 27 Javascript
微信小程序实现通过双向滑动缩放图片大小的方法
Dec 30 Javascript
微信小程序实现类似微信点击语音播放效果
Mar 30 Javascript
JavaScript利用html5新方法操作元素类名详解
Nov 27 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函数)
2006/10/09 PHP
在Windows XP下安装Apache+MySQL+PHP环境
2015/02/22 PHP
一波PHP中cURL库的常见用法代码示例
2016/05/06 PHP
PHP设计模式之工厂模式与单例模式
2016/09/28 PHP
PHP的mysqli_rollback()函数讲解
2019/01/23 PHP
用javascript实现自定义标签
2007/05/08 Javascript
jquery插件珍藏(图片局部放大/信息提示框)
2013/01/08 Javascript
js实现简单秒表走动的时钟特效
2020/03/25 Javascript
JavaScript sort数组排序方法和自我实现排序方法小结
2016/06/06 Javascript
JavaScript中Number对象的toFixed() 方法详解
2016/09/02 Javascript
Vue实现百度下拉提示搜索功能
2017/06/21 Javascript
深入理解Angular中的依赖注入
2017/06/26 Javascript
基于zepto.js实现手机相册功能
2017/07/11 Javascript
Vue内容分发slot(全面解析)
2017/08/19 Javascript
微信小程序 wepy框架与iview-weapp的用法详解
2019/04/10 Javascript
微信小程序之 catalog 切换实现解析
2019/09/12 Javascript
vue的三种图片引入方式代码实例
2019/11/19 Javascript
jQuery实现验证用户登录
2019/12/10 jQuery
关于JavaScript数组去重的一些理解汇总
2020/09/10 Javascript
Python在Windows和在Linux下调用动态链接库的教程
2015/08/18 Python
python生成tensorflow输入输出的图像格式的方法
2018/02/12 Python
Python使用while循环花式打印乘法表
2019/01/28 Python
计算机二级python学习教程(2) python语言基本语法元素
2019/05/16 Python
python发送多人邮件没有展示收件人问题的解决方法
2019/06/21 Python
python实现几种归一化方法(Normalization Method)
2019/07/31 Python
解决TensorFlow模型恢复报错的问题
2020/02/06 Python
python+appium+yaml移动端自动化测试框架实现详解
2020/11/24 Python
python中把元组转换为namedtuple方法
2020/12/09 Python
python opencv肤色检测的实现示例
2020/12/21 Python
Python爬取梨视频的示例
2021/01/29 Python
python 利用panda 实现列联表(交叉表)
2021/02/06 Python
亚马逊西班牙购物网站:amazon西班牙
2017/03/06 全球购物
美国巧克力喷泉品牌:Sephra
2019/05/05 全球购物
教师演讲稿开场白
2014/08/25 职场文书
教师见习报告范文
2014/11/03 职场文书
公安纪律作风整顿心得体会
2016/01/23 职场文书