extjs源码分析-Ext.util.TaskRunner(模拟多线程)

/** 
* @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();


你可能感兴趣的:(extjs源码分析-Ext.util.TaskRunner(模拟多线程))