Asynchronous flow control library.
= ->consolelog 'load the data and wait'http = require 'http'options =host: 'google.com'port: 80path: ''=responsesetEncoding 'utf8'=consolelog "data loaded "responseon 'data'handleData# here we wait as wellresponseon 'end'renderContent# here we waithttpget optionshandleHTTPGet= ->consolelog 'now render the page'# this is where we initiate the sequenceloadData
The overall flow here is:
Understanding this flow requires reading through the program. It would be better if you could put loadData and renderContent next to eachother:
orc = require'./src/orc'orc= ->consolelog 'load the data and wait'http = require 'http'options =host: 'google.com'port: 80path: ''=responsesetEncoding 'utf8'=consolelog "data loaded "responseon 'data'handleData# here we wait as wellresponseon 'end'orcwaitFor# here we waithttpget optionsorcwaitForhandleHTTPGet= ->consolelog 'now render the page'# this is where we initiate the sequenceorcsequence loadDatarenderContent
The important differences are obviously the orc.sequence and two orc.waitFor calls. Both of these programs have the same output:
$ coffee example.coffeeload the data and waitdata loaded <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"><TITLE>301 Moved</TITLE></HEAD><BODY><H1>301 Moved</H1>The document has moved<A HREF="">here</A>.</BODY></HTML>now render the page
You can see that first the content is loaded and only after that is the content rendered.
1) Get orc from npm or bower
# if you're using with node install with npmnpm install orc# if you're using in the browser install with bowerbower install orc
2) Require or script tag orc
orc = require'orc'orc
3) Sequence some functions
= ->= ->orcsequence loadContentrenderContent
4) Wait for some stuff
= ->request = loaderget someDataUrlrequeston 'data'orcwaitForparseData= ->animatordo animationOptions orcwaitFororcsequence loadContentrenderContent
5) Tell orc how to error
= ->request = loaderget someDataUrlrequeston 'data'orcwaitForparseDatarequeston 'error'orcerrorOn= ->animatordo animationOptions orcwaitFororcsequence loadContentrenderContent
6) Handle sequence error instead of erroring
= ->request = loaderget someDataUrlrequeston 'data'orcwaitForparseDatarequeston 'error'orcerrorOn= ->animatordo animationOptions orcwaitForcontext = orcsequence loadContentrenderContent= consolelog " for "
Orc does as much of the bookkeeping as it can. You should almost never need anything more than the sequence, waitFor, and errorOn functions. Like anything else the more you know about orc the easier it is to work with.
Everything begins with you telling orc to sequence some functions. Orc places these condemned functions into an ExecutionContext. The context lets orc keep the details of each execution separated. These details are things like the functions being executed and whether or not the execution is on hold for anything. At this point orc will begin executing, if it's not already.
Orc can execute both dependent and independent sequences. A sequence is dependent when it requires another sequence to complete before it completes. Dependent sequences are called inside of other sequences kinda like this:
orcsequence ->orcsequence ...
Independent sequences on the other hand look kinda like this:
orcsequence ...orcsequence ...
Whether or not one sequence depends on another sequence determines where orc puts the execution context. If the sequence is independent orc will add it alongside whatever other contexts exist. If the sequence is dependent orc will stack the context on top of whichever context depends on it. Orc then manages these dependencies by only executing from the context at the top of of each stack.
The waitFor decorator is simple. First it saves the current context so that later on it can determine which context the decorated function belongs to. Then it returns a function that wraps the callback it was provided.
The decorated function that waitFor returns will set the current context to the context that was saved earlier. This ensures that any waitFor calls made during the callback will be routed to the correct context. At the very end, once it has executed the callback, the waitFor function will call done on the correct context.