写了一个简单的js任务执行工具(publish/subscribe)
- GitHub地址:https://github.com/soulteary/js-tasker
(function (win, $, undefined) {
"use strict";
var DEBUG = true;
var VER = '20140118';
if (!('console' in window)) {
win.console = function () {
return true;
};
}
//用处理计划任务的方式去处理页面中的事物,这些解耦或许会好点?
//有的时候我们会添加很多任务,但是不一定要立即执行,有的可能会先添加,然后等待某一个事件添加完成后才全部执行。
//但是如果有的数据异常,之前的事情不想做了,那么也可以删除队列。
win.task = {
depend: {},
__check__: function (cmd) {
var protectList = ['__check__', 'exec', 'kill', 'add'];
if ($.inArray(cmd, protectList) !== -1) {
throw Error('THIS METHOD DO NOT ALLOW REWRITE.');
return false;
} else {
return true;
}
},
exec: function (cmd, title) {
if (!this.__check__(cmd)) {
return false;
}
if (cmd in this) {
for (var i = 0, j = this[cmd].length; i < j; i++) {
//有依赖先执行依赖策略
if (this.depend[cmd] && this.depend[cmd]['mask']) {
$(this.depend[cmd]).each(function (k, v) {
if ($.inArray(i, v['mask']) !== -1) {
if (v['host'] !== undefined) {
if (DEBUG) {
console.log('#任务正在执行:', title);
}
if (task[cmd][v['host']] !== task[cmd][v['mask']]) {
task[cmd][v['host']] && task[cmd][v['host']].call(),
task[cmd][v['mask']] && task[cmd][v['mask']].call(),
task.kill(cmd, v['mask']),
task.kill(cmd, v['host']);
} else {
task[cmd][v['host']] && task[cmd][v['host']].call(), task.kill(cmd, v['host']);
}
}
}
});
} else if (this.depend[cmd] && !this.depend[cmd]['mask']) {
this.depend[cmd]['host']
if (this.depend[cmd]['host'] !== undefined) {
if (DEBUG) {
console.log('#任务正在执行:', title);
}
task[cmd][this.depend[cmd]['host']] && task[cmd][this.depend[cmd]['host']].call(), task.kill(cmd, this.depend[cmd]['host']);
}
} else if (!this.depend[cmd]) {
if (DEBUG) {
console.log('#任务正在执行[无依赖]:', title);
}
this[cmd][i] && this[cmd][i].call(), this.kill(cmd, i--), j--;
} else {
throw Error('WAITING FOR DEPEND FUNC REG.');
}
}
}
},
add: function (options) {
var cmd = options.cmd;
var func = options.func || function () {
};//默认空事件
var trigger = options.trigger || false; //默认事件不触发
var option = options.option;
var title = options.title || '';
if (!cmd || !this.__check__(cmd)) {
return false;
}
task[cmd] = task[cmd] || [];
task[cmd].push(func);
if (DEBUG) {
console.log('#任务已添加:', title);
}
var exec = function (cmd) {
if (cmd in task) {
task.exec(cmd, title);
}
};
if (option) {
var format = option.match(/(\w+):(\w+)/ig);
if (format) {
var data = option.split(':');
var action = data[0];
var assign = data[1];
switch (action) {
case 'REG':
//如果没有注册过就注册,注册过就更新依赖的内容
if (DEBUG) {
console.log('#更新依赖:', title);
}
this.depend[assign] = this.depend[assign] || {};
if (this.depend[assign]['host'] && task[cmd][this.depend[assign]['host']]) {
this.kill(task[cmd], this.depend[assign]['host'])
}
this.depend[assign]['host'] = $.inArray(func, task[cmd]);
if (trigger === true) {
exec(cmd);
}
break;
case 'DEP':
//添加任务的时候,如果存在依赖的任务就执行掉。
//否则注册这个事件,但是主题执行的留空
if (DEBUG) {
console.log('#调用依赖:', title);
}
if (this.depend[assign]) {
task[cmd][this.depend[assign]].call(null);
delete this.depend[assign];
//这里或许需要把关联数组内的函数也全部执行一遍
if (trigger === true) {
exec(cmd);
}
} else {
this.depend[assign] = {};
this.depend[assign]['mask'] = this.depend[assign]['mask'] || [];
this.depend[assign]['mask'].push($.inArray(func, task[cmd]));
}
break;
}
}
} else {
if (trigger === true) {
exec(cmd);
}
}
},
kill: function (cmd, i) {
if (!this.__check__(cmd)) {
return false;
}
task[cmd].splice($.inArray(task[cmd][i], task[cmd]), 1);
if (!task[cmd].length) {
delete task[cmd];
}
if (DEBUG) {
console.log('#删除了一个任务。');
}
},
version:VER
};
})(window, jQuery);
//SETTIMEOUT 模拟和服务器交互的接口的延迟,异步执行,等待执行。
//1.首先添加一个睡懒觉的任务,这个任务不会主动触发 trigger: false
//并且没有任何依赖 option: false
setTimeout(function () {
var taskContent = {
title: '1.想要睡懒觉',
cmd: 'notice',
trigger: false,
option: false,
func: function () {
console.log(' >>>明天睡懒觉,这个事件被其他的事件触发了。');
}
}
task.add(taskContent);
}, 100);
//2.然后添加一个计划起床的任务,这个任务会主动触发 trigger: true,
//并且在触发的时候将之前同组没有触发的任务也触发掉
setTimeout(function () {
var taskContent = {
title: '2.计划起床',
cmd: 'notice',
trigger: true,
option: false,
func: function () {
console.log(' >>>计划有变,早点起床,这个任务会触发所有睡觉相关任务。');
}
}
task.add(taskContent);
}, 300);
//3.接着添加一个出门前穿衣服的计划,这个计划有依赖,依赖为getup。
//即使trigger: true,如果没有依赖存在,他是不会执行的
//注意cmd和option中的事件需要一致,比如都是getup
setTimeout(function () {
var taskContent = {
title: '3.声明出门前穿衣服',
cmd: 'getup',
trigger: true,
option: 'DEP:getup',
func: function () {
console.log(' >>>出门,但是要先穿上衣服。');
}
}
task.add(taskContent);
}, 500);
//4.最后添加一个穿衣服的任务,这个任务注册事件为getup,会执行所有的依赖这个家伙的任务
setTimeout(function () {
var taskContent = {
cmd: 'getup',
func: function () {
console.log(' >>>起床,穿上衣服。');
},
trigger: true,
option: 'REG:getup',
title: '4.最后注册起床穿衣服'
}
task.add(taskContent);
}, 1500);
//5.随便注册一个函数并执行,没有依赖也无所谓
setTimeout(function () {
var taskContent = {
cmd: 'nerd',
trigger: true,
func: function (e) {
console.log(' >>>发呆。')
},
option: 'REG:nerd',
title: '5.发呆....'
}
task.add(taskContent);
}, 1500);