`
y1d2y3xyz
  • 浏览: 252526 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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();

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics