TaskRunner 在浏览器提供的 setTimout()/setInterval() 基础上继续完善, 扩展了主要两项功能:执行次数的限制、执行时间的限制(即超时)。TaskRunner 旨在利用计时器分时执行方法提供一个相对简易的并行运行机制,其目的不但在于一般的延时执行任务(或者另一个类 DelayedTask 会更合适),还可以同时进行多项任务。这样的话,任意个独立的任务都可以在任何时候开始,并彼此独立地运行。那么是否与多线程的概念有些相近呢?其实不尽然——这里必须说明一下,尽管 ExtJS 官方文档提出“提供以多线程的方式执行一个或多个任务的能力 Provides the ability to execute one or more arbitrary tasks in a multithreaded manner……”的概念,但并不是真正的代替“线程(thread)”,仅仅是“模拟”。因为我们晓得,浏览器接口也好,JS运行时也好,仍不出“单线程模型”的范围内,所以我们认为充其量只是模拟线程的一种手段。在内部结构中,由数组 tasks[] 保持着任务对象的队列。每个任务对象详细的接口如下:
run
: Function 任务每次运行时执行的函数。该函数将在每次间隔后被调用并传入args
参数,如果该项被指定了的话。 如果需要特定的作用域,请保证设置了scope 参数。
interval
: Number 以毫秒为单位表示的任务执行的间隔。args
: Array (可选项) 一个由传递给run
所指定的函数的参数组成的数组。若不指定则为当前的步进值,即源码中的taskRunCount。scope
: Object (可选项)run
指定的函数的作用域。默认为当然任务对象。duration
: Number (可选项) 任务在自动停止前的执行时长(默认为无限制)。repeat
: Number (可选项) 任务在自动停止前的执行次数(默认为无数次)。
在 TaskRunner 调用方式上,允许开发者以一般“实例化”对象的调用,这点与 setTimout()/setInterval() 的语法截然不同
- // 开始一个简单的每秒更新 DIV 的定时任务
- var updateClock = function(){
- Ext.fly('clock').update(new Date().format('g:i:s A'));
- }
- var task = {
- run: updateClock,
- interval: 1000 //1 second
- }
- var runner = new Ext.util.TaskRunner();
- runner.start(task);
你不但可以实例化 TaskRunner 来制定一个任务,还可以透过调用单例方法 Ext.TaskMgr() 完成,作用无异,例如:
- // 开始一个简单的每秒更新 DIV 的定时任务
- var task = {
- run: function(){
- Ext.fly('clock').update(new Date().format('g:i:s A'));
- },
- interval: 1000 //1 秒
- }
- Ext.TaskMgr.start(task);
欲并行执行多个任务(或说方法)可以设置 interval 配置项非常短的时间,比如10ms。另外注意,如果run 函数返回了 false 值,则该任务中止,撤销计时器(不能恢复)。stop()是撤销队列中指定任务的方法(不能恢复),stopAll()是停止所有任务的方法。
每次初始化 Task 时都会自动记录当前时间的量 taskStartTime,并保存在任务对象身上。执行任务之后,如果超出允许的运行时间范围则中止任务(参见:t.duration && t.duration <= (now - t.taskStartTime))。运行次数的限制亦如法炮制。
TaskRunner 在 Ext JS 1.x ~4.x中通过,注意单例 Ext.TaskMgr 的命名空间在 ExtJS 4中稍有不同,为 Ext.TaskManager。