js下写一个事件队列操作函数_javascript技巧

前两天在网上看到这一系列的文章《写一个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试了一下恩,看来还是没问题的。

时间: 2024-09-18 14:41:15

js下写一个事件队列操作函数_javascript技巧的相关文章

js实现的星星评分功能函数_javascript技巧

本文实例讲述了js实现的星星评分功能函数.分享给大家供大家参考,具体如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head&

JS下拉缓冲菜单示例代码_javascript技巧

复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <style> body,html

js 字符串操作函数_javascript技巧

concat() – 将两个或多个字符的文本组合起来,返回一个新的字符串. indexOf() – 返回字符串中一个子串第一处出现的索引.如果没有匹配项,返回 -1 . charAt() – 返回指定位置的字符. lastIndexOf() – 返回字符串中一个子串最后一处出现的索引,如果没有匹配项,返回 -1 . match() – 检查一个字符串是否匹配一个正则表达式. substring() – 返回字符串的一个子串.传入参数是起始位置和结束位置. replace() – 用来查找匹配一个

JS针对Array的各种操作汇总_javascript技巧

Array应该是我们在平时写js代码中,使用频率最高的,在平时的项目中,很多数据都是可以通过Array来存储.操作等任务.除了Object之外,Array类型应该是js中最常用的类型了. 今天总结一下Array的一些简单和基本的操作,也来巩固下自己的基础知识. 一.如何创建Array(下面直接说数组) 创建数组主要有两种方法,第一种是使用数组构造函数,第二种是使用数组字面量表示法. 1.使用数组构造函数 如:var arr = new Array(); 如果预先知道数组的长度,那么也可以直接给构

js对象之JS入门之Array对象操作小结_javascript技巧

不过在学脚本prototype.js的过程中发现有些方法我们很少用到,但是有些方法好像很经典,脚本库在不断的加大,眼前一片...继续我们JS入门,今天学习一下Array数组. 首先我们来看看它的定义: 复制代码 代码如下: var arrayObj = new Array() var arrayObj = new Array([size]) var arrayObj = new Array([element0[, element1[, [, elementN]]]]) 其中:arrayObj是赋

显示js对象所有属性和方法的函数_javascript技巧

要想看到实际效果,可以先声明一些属性跟方法,否则是看不到,仔细往下看有例子的. 复制代码 代码如下: function ShowObjProperty(Obj) { var PropertyList=''; var PropertyCount=0; for(i in Obj){ if(Obj.i !=null) PropertyList=PropertyList+i+'属性:'+Obj.i+'\r\n'; else PropertyList=PropertyList+i+'方法\r\n'; }

给应用部分的js代码设定一个统一的入口_javascript技巧

javascript是种脚本语言,浏览器下载到哪儿就会执行到哪儿,这种特性会为编程提供方便,但也容易使程序过于凌乱,支离破碎. js从功能上可以分为两大部分--框架部分和应用部分,框架部分提供的是对js代码的组织作用,包括定义全局变量.命名空间方法等,每个页面都会有相同或类似的框架.应用部分提供的是页面功能逻辑,不同页面会有不同的功能,不同页面应用部分的代码也不尽相同. 给应用部分的js代码一个统一的入口,即: 复制代码 代码如下: <script type="text/javascrip

JS 自定义带默认值的函数_javascript技巧

开始想当然地认为可能像php或python等语言中一样 js 代码 复制代码 代码如下: function test(a,b="er"){ alert(a + b ); } 可是,定义完之后一直在报错:缺少对象.经过查询才发现,javascript中的确不能这样定义,可以借肋于arguments 是实参数组,参考下例: js 代码 复制代码 代码如下: <script type="text/javascript"> function Test(a) {

JS+CSS实现一个气泡提示框_javascript技巧

分享一个气泡提示框,练习的技术有:(1)JS响应鼠标的事件:(2)纯CSS制作三角形. 效果这样:  这是html: 复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>气泡对话框</title> <script src="myBubbleTooltip.js"></script>