Swiz provides a simple, yet powerful and extensible API for chaining actions together. At the heart of this API are the IChain and IChainStep interfaces. Let's look at them here, starting with IChain.
<script src="http://gist.github.com/410557.js?file=IChain.as"></script>
Most of the methods are self explanatory, so we'll only discuss the most important one directly. The doProceed() method is where a chain does its work. It's where EventChain dispatches events, and where CommandChain executes commands. If you clicked either of those links, you may have noticed that both chain types contain very little code other than their doProceed() implementations. This is because they both extend AbstractChain, which implements the entire IChain interface besides doProceed(). It does not actually implement IChain, however, which forces custom chain types to do so and to implement doProceed(). AbstractChain does implement IChainStep though, which means chains can be nested. Also note that chains can be run in either sequence or parallel mode, with constants defined for each in the ChainType class.
<script src="http://gist.github.com/410557.js?file=IChainStep.as"></script>
IChainStep is the base interface for objects that can be part of a chain. The methods are again pretty self explanatory, but do notice the complete() and error() methods, which correspond to the stepComplete() and stepError() methods of IChain.
The last interface of the Swiz chaining API is IAutonomousChainStep.
<script src="http://gist.github.com/410557.js?file=IAutonomousChainStep.as"></script>
While chains will often have specific logic for executing their constituent steps, sometimes it is beneficial for a step to control its own execution. This is especially useful for constructing chains with steps of varying types.
Provided implementations
Swiz provides some useful implementations of the chaining API for you. We previously mentioned EventChain, which is exactly what it sounds like. It allows you to string together EventChainStep instances, and also supports IAutonomousChainStep instances. EventChains can be extremely useful for things like application boot strapping and making multiple remote service calls.
CommandChain provides a mechanism for assembling CommandChainStep instances, as well as AsyncCommandChainStep instances (they extend CommandChainStep and implement IResponder) and implementations of IAutonomousChainStep.
FunctionChainStep is another useful class that implements IAutonomousChainStep and allows for deferred function invocation.
Finally, note that BaseChainStep provides a base implementation of IChainStep, making your custom implementations that much easier to write.
Custom implementations
It is extremely easy to extend the chaining API to meet your specific needs. As mentioned above, creating a custom chain type essentially boils down to extending AbstractChain, adding "implements IChain" and then implementing the doProceed() method. Your doProceed() method could execute custom chain step types, log or otherwise audit chain progress or perform any other custom behavior you desire. A simple chain that relies on autonomous steps is shown below.
<script src="http://gist.github.com/405843.js?file=CompositeChain.as"></script>
Custom chain steps can be made to perform virtually any action. They will need to implement IChainStep, which is most easily done by extending BaseChainStep. If they implement IAutonomousChainStep they can be virtually self contained, and can easily be combined with other chain step types. A couple of examples of custom chain steps can be seen below.
<script src="http://gist.github.com/405843.js?file=PropertySetterStep.as"></script>
<script src="http://gist.github.com/405843.js?file=DispatchEventStep.as"></script>
Automatic Asynchronous Handling in Chains
The Event Chaining API supports asynchronous handling in a "pay-as-you-go" manner.
[EventHandler]
methods may return either AsyncToken or IAsynchronousOperation to participate in automatic asynchronous handling.
Not all asynchronous Flash or Flex API operations return AsyncToken. Consequently, we base the internal logic related to asynchronous handling around IAsynchronousOperation.
Swiz provides three concrete implementations that adapt typical Flash / Flex asynchronous operations into IAsynchronousOperations.
- AsyncTokenOperation - which adapts an AsyncToken.
- AsynchronousChainOperation - which adapts an asynchronous IChain.
- AsynchronousIOOperation - which adapts Flash or Flex API operations that signal success or failure by dispatching Event.COMPLETE / Event.CANCEL / IOEvent.IO_ERROR / SecurityErrorEvent.SECURITY_ERROR events (ex. FileReference).
NOTE: AsynchronousIOOperation extends AbstractAsynchronousDispatcherOperation - you can extend this abstract base class to adapt other asynchronous operations that signal their success or failure via Events.
As noted earlier, [EventHandler]
methods can still just return an AsyncToken - [EventHandler]
will automatically adapt the token via AsyncTokenOperation.
Only IAsynchronousEvent and AsynchronousEvent can be chained with automatic asynchronous handling.
For example, these changes mean you can now create a mediator like this:
<script src="http://gist.github.com/659216.js?file=EventHandler_asynchronous_operation.as"></script>
An [EventHandler]
method can dynamically construct an asynchronous chain and return that chain as an operation (adapting it via AsynchronousChainOperation). In that case, the original EventChainStep will not proceed until that operation is complete.
Go forth and chain stuff!
Hopefully this page has shown you the ease, power and extensibility of the Swiz chaining API. If you have questions or comments about the API or any of the built in implementations, or even just ideas you'd like to discuss, please head over to the mailing list and we'll be happy to help!