/ javascript

原生js 实现事件队列

/**
原生js 实现事件队列
EventQueue —— Events Queue
@method add(Function) 下一个要执行的事件。
@method wait(Number) 等待一定时间后执行下一个事件。
@method sleep() 停止事件序列的执行。
@method wake() 继续执行事件序列。
**/
var EventQueue = function () {
//添加任务
this.queue = [];
this.status = "running";
return this;
}
EventQueue.prototype = {
add: function (callback, async) {
var fnObj = {
action: callback,
async: async
}
this.queue.push(fnObj);
return this;
},
wait: function (delay) {
var self = this;
this.add(function () {
setTimeout(function () {
self.wake.call(self)
}, delay);
}, true);
return this;
},
//按事件添加的先后顺序依次执行事件
go: function () {
if (this.queue.length === 0) return;
while (this.queue.length > 0) {
if (this.status === "sleep") return;
var fun = this.queue.shift();
if (fun.async) {
this.sleep();
fun.action(function () {
//异步函数必须有回调函数唤醒队列
eventQueue.wake();
});
} else {
fun.action();
}
}
},
sleep: function () {
this.status = "sleep";
},
wake: function () {
this.status = "running";
this.go();
}
}
// 测试
var eventQueue = new EventQueue();
// 添加几个事件,依次执行
eventQueue.add(e1);
eventQueue.add(e2, true);
eventQueue.add(e3);
eventQueue.wait(2000);
eventQueue.add(e3);
eventQueue.add(e4, true);
eventQueue.add(e6);
eventQueue.go();

function e1() {
console.log(1);
}

function e2(fn) {
setTimeout(function () {
console.log(2);
fn();
}, 3000);
}

function e3() {
console.log(3);
}

function e4(fn) {
fetch('/')
.then(res => {
console.log(res);
console.log(4);
fn();
})
.catch(err => {
console.log(err);
console.log(5);
fn();
});
}

function e6() {
console.log(6);
}

//链式屌用
eventQueue
.add(function () {
console.log(1);
})
.add(function (fn) {
setTimeout(function () {
console.log(2);
fn()
}, 2000);
}, true)
.add(function () {
console.log(3);
})
.wait(1000)
.add(function () {
console.log(4);
})
.add(function () {
console.log(5);
})
.go();