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访问XML数据的实例
Dec 27 Javascript
从JavaScript的函数重名看其初始化方式
Mar 08 Javascript
小型js框架veryide.librar源代码
Mar 05 Javascript
用jquery ajax获取网站Alexa排名的代码
Dec 12 Javascript
jQuery表格排序组件-tablesorter使用示例
May 26 Javascript
理解javascript中的回调函数(callback)
Sep 02 Javascript
jQuery实现右键菜单、遮罩等效果代码
Sep 27 Javascript
JS针对Array的各种操作汇总
Nov 29 Javascript
vue2.x select2 指令封装详解
Oct 12 Javascript
vue实现商城秒杀倒计时功能
Dec 12 Javascript
Vue简单封装axios之解决post请求后端接收不到参数问题
Feb 16 Javascript
el-table树形表格表单验证(列表生成序号)
May 31 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的PDO预定义常量讲解
2019/01/24 PHP
PHP如何使用cURL实现Get和Post请求
2020/07/11 PHP
jQuery实现滚动切换的tab选项卡效果代码
2015/08/26 Javascript
Jquery easyui开启行编辑模式增删改操作
2016/01/14 Javascript
原生js和jquery分别实现横向导航菜单效果
2016/05/13 Javascript
vue实现未登录跳转到登录页面的方法
2018/07/17 Javascript
解决vue.js 数据渲染成功仍报错的问题
2018/08/25 Javascript
express+vue+mongodb+session 实现注册登录功能
2018/12/06 Javascript
JS面向对象实现飞机大战
2020/08/26 Javascript
[47:53]DOTA2上海特级锦标赛主赛事日 - 1 败者组第一轮#2COL VS Spirit
2016/03/02 DOTA
Python二分查找详解
2015/09/13 Python
Python正确重载运算符的方法示例详解
2017/08/27 Python
Pandas中把dataframe转成array的方法
2018/04/13 Python
基于Python中求和函数sum的用法详解
2018/06/28 Python
Python随机生成身份证号码及校验功能
2018/12/04 Python
Python线程之定位与销毁的实现
2019/02/17 Python
在Django model中设置多个字段联合唯一约束的实例
2019/07/17 Python
用Python徒手撸一个股票回测框架搭建【推荐】
2019/08/05 Python
python logging.basicConfig不生效的原因及解决
2020/02/20 Python
python3 logging日志封装实例
2020/04/08 Python
PyCharm 解决找不到新打开项目的窗口问题
2021/01/15 Python
7款设计巧妙的css3飘带状3D立体效果的导航菜单和表单窗口
2013/02/04 HTML / CSS
墨西哥运动服饰和鞋网上商店:Netshoes墨西哥
2016/07/28 全球购物
Perfume’s Club英国官网:购买香水和护肤品
2019/11/02 全球购物
如何开发安全的AJAX应用
2014/03/26 面试题
如何定义一个可复用的服务
2014/09/30 面试题
自考生毕业自我鉴定
2013/10/10 职场文书
《果园机器人》教学反思
2014/04/13 职场文书
小学生期末评语大全
2014/04/21 职场文书
助人为乐好少年事迹材料
2014/08/18 职场文书
创先争优个人承诺书
2014/08/30 职场文书
贫困证明模板(3篇)
2014/09/16 职场文书
开展党的群众路线教育实践活动工作总结
2014/11/05 职场文书
大学生个人简历自荐信
2015/03/06 职场文书
Redis Cluster 字段模糊匹配及删除
2021/05/27 Redis
Python 的 sum() Pythonic 的求和方法详细
2021/10/16 Python