Getjs
JavaScript library to express concurrency patterns.
Getjs is a control flow library based in generators to simplify the development of concurrent solutions for JavaScript. It works in both nodejs and the browser, allowing you to deal with the JavaScript asynchronous nature by writting sequential code.
Getjs implements Communicating Sequential Process(CSP) by emulating Golang concurrency primitives as much as possible with few deviations to fit in the JavaScript ecosystem. It works with every library based on Promises.
Pingpong example (ported from Go)
var player = get
Documentation
- Installation
- Coroutines
- Channels
- Parallel Resolution
- Race Resolution
- Pausing Coroutines
- Promisifying
- Idiomatic Getjs
- Debugging
Installation
Browser
Nodejs
var get =
Coroutines
Coroutines are functions that runs asynchronously. The body of coroutines are generator functions, each time a promise is yielded inside a coroutine it blocks until the promise is resolved or rejected. Each coroutine execution returns a promise that is resolve when the coroutine returns, or rejected if an error occurs.
Spawning a coroutine.
get // with argumentsget
In many occasions you may need to declare coroutines to spawn it on demmand.
var worker = get
Waiting for a promise.
get
Promise flow.
get
Channels
Channels are structures used to communicate and synchronize coroutines. The behavior is exactly like in Go language.
Channels can be buffered or unbuffered. When sending data through unbuffered channels it always blocks the sender until some other process receives. Once the data has been received, the sender will be unblocked and the receptor will be blocked until new data is received. Unbuffered channels are also known as synchronic channels.
// create new channelvar ch = get get get
get.send
andget.recv
operations must preceded by theyield
keyword.
When some data is sent to a buffered channel it only blocks the coroutine if the buffer is full. The receiver only blocks if there is no data in the buffer.
var bufferSize = 20var ch = get
Values passed through channels can be tranformed before to be delivered.
{ return x*2} // provide a transformervar ch =
Channels can be closed using get.close
function, sending to a closed channel will throw an error. ch.closed
and ch.opened
allows to know whether a channel is closed or not.
whilechopened get // close it somewhere in your codeget
Parallel Resolution
You can wait for many tasks executed in parallel by using get.all
.
// proding an array of promisesvar result = getall $ $; var books = result0;var authors = result1;
You can cast by keys by using objects.
// roviding an objectvar result = getall books: $ authors: $; var books = resultbooks;var authors = resultauthors;
Race Resolution
get.race
returns promise that resolves once one of them has been resolved. The returned promise resolves with an object whith the format {which: key, value: value}
.
get
Also support objects.
get
Pausing Coroutines
Some times you want to block a couroutine a span of time.
// stop by 20 milliseconds get
Promisifying
It is possible to adapt callback-based API to be used with Getjs.
var fs = // make the callback-based function returns a promisevar stat = get get
Also you can promisify the entire module.
var fs = get get
Idiomatic Getjs
The get
function is overloaded, making possible to write more succint code. If the first parametter is a generator function it will relay on get.wrap
else it will try to convert the value to a promise through get.recv
if channel, or get.all
is object or array is provided.
// wrapped coroutinefunc = // receive from a channel // parallel resolution
Debugging
Coroutine errors are easy to handle because the promise catch
function. During development all coroutine errors are logged to the console. For production you should avoid this behaviour by turning get.debug
to false
.
get.debug = false
(c) 2016 Yosbel Marín