更新日期:2010年8月5日
1.Task简介
FLEX应用程序可能需要多个异步处理,比如modules和stylesheets 加载,或者service的依次调用,都可以使用Cairngorm Task类库。
Task类库的功能:
管理异步任务的时序
多个任务的并发执行
任务可以包含子任务,所有子任务都完成后,父任务才结束。
派发一组件事件去批导处理
相关的Task类库有好几个,这里只描述三个Task类库,还有几个Task类库以后再描述。
2.Cairngorm Task
Cairngorm Task是一个可以顺序和并行执行的类库,其特点如下:
* 顺序或并行处理任务.
* 支持任务的嵌套处理.
* 可以在MXML或actionscript中声明
* 可以在视图组件中使用binding标签.
* 派发事件去指导处理.
* 支持条件选择,可以跳过任务.
3.Spicelib Task Framework
Spicelib Task Framework是Spicelib 类库的一部分。This task framework有几个方面比cairngorm task更强大一些,支持任务挂起、恢复、取消及其它。但是,并不是在MXML中定义,也不能使用bindable属性。如果在后续版本中添加这些特征,将完全取代Cairngorm Task liberary。
4.SequenceCommand
SequenceCommand 类有时候也应该在cairngorm1和2项目中。它的目的是初始化其它的cairngorm命令,比如:当一个命令完成了处理后,有一系列命令需要执行。这个方法并不好,因为它需要给一个命令给下一个命令提供必要的信息,限制了复用性,提高了命令的复杂度。
5.Cairngorm Task举例
这个例子是应用程序的初始化部分。可能一个初始化service调用任务去获取用户配置信息,再调用一系列子任务去获取用户需要的数据。一些modules和style-sheets将在启动过程中加载。
例1:在MXML中定义一个任务
xmlns:mx=""
xmlns:task="com.adobe.cairngorm.task "
xmlns:example="com.adobe.cairngorm.task.example">
本例中描述一个任务的次序,从LoadUserProfile开始。当用户配置信息获取后,LoadNews和LoadContacts并发执行。当这二个都完成后,并发加裁module。所有module都加载成功后,任务结束。
例2:actionscript代码举例
var parallel1:ParallelTask = new ParallelTask();
parallel1.addChild(new LoadNews());
parallel1.addChild(new LoadContacts());
var parallel2:ParallelTask = new ParallelTask();
parallel2.addChild(new LoadModule(""));
parallel2.addChild(new LoadModule(""));
parallel2.addChild(new LoadStylesheet(""));
parallel2.addChild(new LoadStylesheet(""));
var task:SequenceTask = new SequenceTask();
task.addChild(new LoadUserProfile());
task.addChild(parallel1);
task.addChild(parallel2);
上面的代码功能与MXML相同。
例3:启动一个任务
一旦任务完成了初始化,就可以通过start()函数启动。
task.start();
任务如果成功结束,派发事件TaskEvent.TASK_COMPLETE;如果遇到错误结束,派发事件TaskEvent.TASK_ERROR。
可以在MXML中定义事件处理器:
id="task"
taskComplete="doSomething()"
taskError="doSomethingElse()"/>
也可以在 ActionScript中定义事件处理器
task.addEventListener(TaskEvent.TASK_COMPLETE, taskCompleteHandler);
task.addEventListener(TaskEvent.TASK_FAULT, taskFaultHandler);
例4:自定义任务
The Cairngorm Task library包含并行任务ParallelTask 和 串行任务SequenceTask 。
开发人员可以实现接口ITask 或者扩展Task类自定义一个任务。
下面是一个最简单的方法:
public class HelloWorld extends Task
{
override protected function performTask():void
{
trace("Hello World!");
complete();
}
}
说明
这里覆盖了performTask()方法,并用在任务结束后,调用了 complete() 或 fault()函数。
In reality, tasks are likely to invoke asynchronous service calls or integrate with other systems, like a local SQLite database. Here is a more realistic example:
实际上,任务中也可以调用异步service去集成其它系统,比如本地的SQL访问服务,例子如下:
public class LoadUserProfile extends Task
{
override protected function performTask():void
{
var service:HttpService = new HttpService();
service.url = "";
service.addEventListener(ResultEvent.RESULT, onResult);
service.addEventListener(FaultEvent.FAULT, onFault);
service.send();
}
private function onResult(event:ResultEvent):void
{
service.removeEventListener(ResultEvent.RESULT, onResult);
// do something with result
complete();
}
private function onFault(event:FaultEvent):void
{
service.removeEventListener(FaultEvent.FAULT, onFault);
error(event.fault.message);
}
}
说明
本例中,performTask()函数创建一个新的服务实例和两个事件处理器。如果正确返回,则调用onResult(),如果错误返回,则调用onFault()。
例5:简单而完整的任务举例
功能:
本例通过preloader实现加载时自动启动任务和点击按钮启用任务
TaskFlowExample.mxml
preloader="sample.TaskFlowPreloader"/>
taskProgress="progressBar.setProgress( event.processed, event.size )"/>
width="300"
mode="manual"/>
TaskFlowPreloader.as
功能
这个类继承了接口IPreloaderDisplay,用户显示加载过程中的内容
关键代码
// 实现接口IPreloaderDisplay.set preloader(),添加事件监听
public function set preloader(preloader:Sprite):void
{
preloader.addEventListener(ProgressEvent.PROGRESS, handleProgress);
preloader.addEventListener(Event.COMPLETE, handleComplete);
preloader.addEventListener(FlexEvent.INIT_PROGRESS, handleInitProgress);
preloader.addEventListener(FlexEvent.INIT_COMPLETE, handleInitComplete);
}
// 实现IPreloaderDisplay.initialize()
public function initialize():void
{
labelText = new TextField();
labelText.scaleX = 5;
labelText.scaleY = 5;
labelText.width = 600;
labelText.y = 330;
labelText.x = 300;
addChild(labelText);
labelText.text = "Loading Flex Framework";
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function handleInitComplete(event:Event):void
{
//创建任务并运行
var taskgroup:ITaskGroup = new ExampleTasks();
taskgroup.addEventListener(TaskEvent.CHILD_START, onChildStart);
taskgroup.addEventListener(TaskEvent.TASK_PROGRESS, onTaskProgress);
taskgroup.addEventListener(TaskEvent.TASK_COMPLETE, onTaskComplete);
taskgroup.start();
}
ExampleTasks.mxml
功能
定义了多个任务的执行顺序
label="initialization"
xmlns:mx=""
xmlns:example="sample.*"
xmlns:cairngorm="com.adobe.cairngorm.task.*">
TimedTask.as
功能
定义了一个简单的任务,该任务必须继承Task类,并覆盖方法performTask()
public class TimedTask extends Task
{
private var timer:Timer;
public var delay:Number = 2000;
override protected function performTask():void
{
timer = new Timer(delay, 1);
timer.addEventListener(TimerEvent.TIMER, onTimer);
timer.start();
}
private function onTimer(event:TimerEvent):void
{
timer.removeEventListener(TimerEvent.TIMER, onTimer);
timer = null;
complete();
}
}
功能说明:程序启动过程中,显示各个任务的label。用户点击按钮时,程序显示任务总数和已完成的任务数
注意:对于并发执行的任务,label的切换显示十分快,而不是不显示。
详细代码见项目:CairnTaskProject.rar
待研究
1.如何把parsley中的command层与Task结合起来使用,
2.官方网站给出了loadmodule,loadStylesheet,loadRestFul的任务类,但是没有调用演示。
总结
所有代码详见项目CairnTaskProject.rar
项目开发环境:flex_sdk_4.0.0.14159,task1.7.swc
参考文献
1.Performing Tasks in Sequence and Parallel .
阅读(2438) | 评论(0) | 转发(1) |