/**
* @class Ext.util.TaskRunner
* @description 模拟多线程的JS类
//一个简单的更新闹钟时间的任务
var updateClock = function(){
Ext.fly('clock').update(new Date().format('g:i:s A'));
}
var task = {
run: updateClock,
interval: 1000 //1 秒
}
var runner = new Ext.util.TaskRunner();//实例化一个线程管理器
runner.start(task);//开始执行task线程
//下面是简易的写法
Ext.TaskMgr.start({
run: updateClock,
interval: 1000
});
* 对比查看{@link Ext.util.DelayedTask}.
* @constructor
* @param {Number} interval 这个设置线程管理器的执行时间,默认为10毫秒
* (defaults to 10)
*/
Ext.util.TaskRunner = function(interval){
interval = interval || 10;
var tasks = [], //任务集合
removeQueue = [],//被移除的任务
id = 0,//定时器ID
running = false,//是否正在执行
// private
stopThread = function(){//停止执行,并把running 和 id 重置
running = false;
clearInterval(id);
id = 0;
},
// private
startThread = function(){//开始执行,确定当前进程还没执行
if(!running){
running = true;
id = setInterval(runTasks, interval);
}
},
// private
removeTask = function(t){//删除进程,
removeQueue.push(t);//把不要再执行的进程放到removeQueue数组中,以等待下次执行其他进程的时候把删除掉
if(t.onStop){//进程停止后的回调函数
t.onStop.apply(t.scope || t);
}
},
// private
runTasks = function(){
var rqLen = removeQueue.length,//获取被
now = new Date().getTime();
if(rqLen > 0){
for(var i = 0; i < rqLen; i++){
tasks.remove(removeQueue[i]);//把removeQueue中的值从tasks中移除
}
removeQueue = [];//重新重置 removeQueue
if(tasks.length < 1){//如果进程数为0,那直接返回,并停止当前正在执行的进程
stopThread();
return;
}
}
for(var i = 0, t, itime, rt, len = tasks.length; i < len; ++i){
t = tasks[i];
itime = now - t.taskRunTime;//当前时间 - 线程的最后一次运行的时间
//因为这个函数默认的interval为10,也就是整个线程实例是每隔10毫秒会去监控一次是否有需要运行的任务,
//这样做的原因是保障每个任务的定时器可以不一样,但都能执行得到,这就是这个函数能支持多个定时任务的原因所在,其实也就是模拟了多线程
if(t.interval <= itime){
rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]);
t.taskRunTime = now;//重新更新当前线程的执行时间
//如果线程结束,则删除当前线程
if(rt === false || t.taskRunCount === t.repeat){
removeTask(t);
return;
}
}
//如果存在 duration 并且已经超出了执行时间了,比如我要求这个线程执行时间 即duration 为一分钟,
//那么我这个任务已经执行时间(当前时间 - 线程开始执行的时间)必须小于 一分钟,否则的话那这个线程就得删除
if(t.duration && t.duration <= (now - t.taskStartTime)){
removeTask(t);
}
}
};
/**
* Starts a new task.
* @method start
* @param {Object} task 配置属性:<ul>
* <li>run : Function 每次执行的回调函数,参数为 下面的 args 或者 当前线程被执行的次数 </li>
* <li>args : Array 这个值穿给上面的function</li>
* <li>scope : Object 线程执行的作用域 默认为当前的线程 </li>
* <li>duration : Number (optional) 执行的时长,单位是毫秒</li>
* <li>repeat : Number(optional) 线程执行的次数</li>
* </ul>
* @return {Object} The task
*/
this.start = function(task){
tasks.push(task);
task.taskStartTime = new Date().getTime();//线程开始执行的时间
task.taskRunTime = 0;//线程执行的的时间 这个是以毫秒为单位的数字 1000便是一秒
task.taskRunCount = 0;//线程执行的次数
startThread();
return task;
};
/**
* @description 停止某个线程执行
* @method stop
* @param {Object} task 被停止的线程
* @return {Object} 返回被停止的线程
*/
this.stop = function(task){
removeTask(task);
return task;
};
/**
* @description 停止所有线程.
* @method stopAll
*/
this.stopAll = function(){
stopThread();
for(var i = 0, len = tasks.length; i < len; i++){
if(tasks[i].onStop){
tasks[i].onStop();
}
}
tasks = [];
removeQueue = [];
};
};
//多线程实例化对象
Ext.TaskMgr = new Ext.util.TaskRunner();