您的位置:首页 > 大数据 > 人工智能

Cairngorm框架中的Chained Event - 如何实现事件序列

2008-11-04 21:40 513 查看
最近在学习Cairngorm框架,并且在Marcus的指导下,利用该框架来完成一个很小的应用(只有一页...)。

Cairngorm下的事件具有异步的特性,比如说,触发10个事件(CairngormEvent),每个事件去调用不同的Server端,并返回XML结构的结果。如果依次触发这10个事件,返回结果的时候,并不一定会是按触发的顺序来分别返回结果的。

事件异步的特性使得数据的取得更灵活,但是也有它的缺点。比如下面的情况:有一系列事件,调用相同的HTTPService服务,通过传递参数的不同,来实现相近的服务器端操作(我在做的是在服务器端,根据JSP数据生成静态的 HTML页面...)。这一系列事件的触发,如果使用普通的Cairngorm的事件机制,则没有办法在事件序列执行过程中,退出序列。因为你并不能确定什么事件已经触发而什么事件还没触发。所以,需要引入Chained Event

主要步骤:
1.自定义一个ChainEvent,继承CairngormEvent。定义一个变量nextChainEvent,以保存下一个Event的对象。
public class ChainEvent extends CairngormEvent
{
public function ChainEvent( type:String )
{
super( type );
}

public var nextChainedEvent:ChainEvent;
}
2.所有要加入序列的事件,都继承自ChainEvent类,初始化这些事件,并使每个事件对象中的nextChainEvent变量保存有下一个事件的对象。
public class EventChainFactory
{
public static function chainEvents( evts:Array ):ChainEvent
{
var len:int = evts.length;
if ( len < 1 )
return null;

var returnEvent:ChainEvent = evts[ 0 ] as ChainEvent;

var i:int = len-1;
for ( i; i>=0; i-- )
{
if ( i != ( len-1 ) )
{
var e:ChainEvent = evts[ i ] as ChainEvent;
var next_e:ChainEvent = evts[ i+1 ] as ChainEvent;
e.nextChainedEvent = next_e;
}
}

return returnEvent;
}
}

3.自定义的Command类要继承SequenceCommand。在处理HTTPService返回值的方法里,首先判断一个保存在 ModelLoacator里的标志位(abortProcess),abortProcess等于true则把下一个事件对象付给nextEvent,然后调用executeNextCommand()。
public class ExecuteBulkGenerationCommand extends SequenceCommand implements ICommand {
private var __model:StaticContentGenModel = StaticContentGenModel.getInstance();
private var __section:SectionVO = null;
private var __event:CairngormEvent = null;

override public function execute(event:CairngormEvent):void {
var responder:Responder = new Responder(onResult_processDone, onFault);
__section = ( event as ExecuteBulkGenerationEvent ).section;
__event = event;
var delegate:ExecuteBulkGenerationDelegate = new ExecuteBulkGenerationDelegate( responder );
delegate.staticContentGen( __section );
}

public function onResult_processDone( event:ResultEvent ):void {
// event结果返回XML结构数据

var path:String = event.result.result.path;
var errorMsg:String = event.result.result.errorMessage;
var processDone:Boolean = event.result.result.success as Boolean;

__model.results.addItem( path );

// 判断全局标志位, 触发下一个序列中的事件

if( !__model.abortGeneration ) {
nextEvent = ChainEvent( __event ).nextChainedEvent;
this.executeNextCommand();
}
}

public function onFault( event:Event ):void {
__model.results.addItem( "Fault on ExecuteBulkGenerationCommand. Section : " +
__section.section + " ; Mode : " + __section.generationMode );
trace("Fault on ExecuteBulkGenerationCommand: " + event.toString());
}
}

4.使用异步机制事件来修改标志位(abortProcess)。

5.调用代码示例
private function build():void
{
// TestAEvent,TestBEvent均继承自ChainEvent,见步骤1

var chain : ChainEvent = EventChainFactory.chainEvents([
new TestAEvent(), new TestBEvent()]);
cgDispatcher.dispatchEvent( chain );
}
参考: http://undefined-type.com/index.php/2008/08/07/cairngorm-chain-events (提供了ChainEvent的主要框架,个人添加了退出事件序列的机制 :P)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: