Skip to content
odf edited this page Oct 17, 2014 · 3 revisions

####go #####csp.go(gen, args...)

Executes a go block. The first argument must be an ES6 generator (created via function*), which is called with the remaining arguments. Go blocks run uninterrupted until a yield is encountered, at which point control is passed to the next (possibly the same) go block that is able to continue.

Returns a deferred value (see below) which is eventually resolved with the return value of the specified generator.

var gen = function*(name) { console.log('Goodbye'); yield null; console.log(name + '!'); };
csp.go(gen, 'callbacks');
csp.go(function*() { console.log('cruel'); });
// prints "Goodbye", then "cruel", then "callbacks!"

####defer #####csp.defer()

Creates a deferred value. A deferred value can be resolved with a value via the resolve method or rejected with an error object via the reject method. Prefixing a deferred value with the yield keyword blocks the current go block until the value is resolved.

A deferred value can be resolved or rejected no more than once, and can be used with a yield no more than once. The method isResolved can be used to test without blocking whether a deferred value has been resolved or not, but there is no supported way to retrieve its value without a yield.

var result = csp.defer();
csp.go(function*() { console.log('Waiting...'); console.log(yield result); });
csp.go(function*() { result.resolve(1); console.log('Resolved!'); });
// prints "Waiting...", then "Resolved!", then 1

####longStackSupport #####csp.longStackSupport

Enables stack rewriting when passing exceptions out of go blocks. This provides more readable stack traces that reflect dynamic calling relationships of go block, but effects an additional memory and runtime cost per go block execution.

csp.longStackSupport = true;

csp.top(csp.go(function*() {
  return yield csp.go(function*() {
    return yield csp.go(function*() {
      throw new Error('Oops!');
    });
  });
}));

####top #####csp.top(deferred)

Registers a callback on the given deferred that prints a stack trace in case of rejection. This is a utility function that simulates the familiar behaviour of uncaught exceptions in code outside of go blocks.

csp.top(csp.go(function*() {
  throw new Error('Oops!');
}));

####join #####csp.join(deferreds)

Accepts an array of deferred values and returns a single deferred that will be resolved to an array of the results.

var delay = function(ms, val) { return csp.go(function*() { yield csp.sleep(ms); return val; }) };
csp.go(function*() { console.log(yield csp.join([delay(200, 2), delay(1000, 3), delay(500, 5)])); });
// pauses for a second, then prints [2, 3, 5]

####lift #####csp.lift(fn, thisBinding)

Creates an asynchronous wrapper around an ordinary function. Arguments to the wrapped function can be an arbitrary mix of immediate and deferred values, and the result is a deferred value.

var asyncArray = csp.lift(Array);
var delay = function(ms, val) { return csp.go(function*() { yield csp.sleep(ms); return val; }) };
csp.go(function*() { console.log(yield asyncArray(delay(200, 2), delay(1000, 3), delay(500, 5))); });
// pauses for a second, then prints [2, 3, 5]

####chain #####csp.chain(start, forms...)

Executes a chain of function calls and returns a deferred value which is eventually resolved with the final result. Start value and intermediate values can be deferred, in which case the next function in the chain is called with the resolved value (via yield). The first argument specifies the start value, each subsequent argument is a form consisting of a function to be called and optionally further arguments to the call.

In the simplest case, a form is just a function object, which is executed with the current value as its sole argument. A form can also be an array consisting of a function, a single argument or array of arguments to be inserted before the current value, and all remaining arguments to be inserted after. Finally, it can be an array starting with a string, in which case the corresponding method is called on the current value, with the remain array elements as arguments.

A form that is none of the above simply replaces the current value with itself.

var plus = function(a, b) { return a + b; };
var div = function(a, b) { return a / b; };
csp.chain(
  csp.go(function*() { yield csp.sleep(1000); return 5; }),
  [csp.lift(plus), 3],       // x -> csp.lift(plus)(3, yield x)
  [csp.lift(div), [], 2],    // x -> csp.lift(div)(yield x, 2)
  console.log);               // x -> console.log(yield x)
// pauses for a second, then prints 4

####sleep #####csp.sleep(ms)

Returns a deferred value that is resolved after the specified number of miliseconds.

csp.go(function*() { console.log('Hello'); yield csp.sleep(1000); console.log('CSP!'); });
// prints "Hello", pauses for a second, then prints "CSP!"

####ncallback #####csp.ncallback(deferred)

Creates a NodeJS-style callback which resolves or rejects the given deferred value as appropriate.

var result = csp.defer();
require('dns').resolve('github.com', csp.ncallback(result));
csp.chain(result, console.log);
/// prints something like [ '192.30.252.129' ]

####nbind #####csp.nbind(fn, thisBinding)

Creates a wrapper for a function following the NodeJS callback conventions. The wrapper returns a deferred value which is eventually resolved or rejected depending on the success of the call.

var dnsResolve = csp.nbind(require('dns').resolve);
csp.chain(dnsResolve('github.com'), console.log);
/// prints something like [ '192.30.252.129' ]

####nodeify #####csp.nodeify(deferred, callback)

Registers a NodeJS-style callback function to be executed when the given deferred value is resolved or rejected. If no callback is given, returns the deferred value as is.

var result = csp.chain(5);
csp.nodeify(result, function(err, val) {
  if (err)
    throw new Error(err);
  else
    console.log(val);
});
/// prints 5

####chan #####csp.chan([sizeOrBuffer])

Creates a new channel. With no argument, the channel is unbuffered, so that a push onto it will block until there is a corresponding pull and vice versa. If a number is given, a buffer of that size is created and calls to push or pull will block if the buffer is full or empty, respectively. Otherwise, the argument must be a buffer object.

####push #####csp.push(channel, value)

Pushes a value onto a channel. Returns a deferred resolving to true upon a successful push or to false if the channel was closed. For channels with a non-standard buffer, a push can be successful even if the value was dropped.

####pull #####csp.pull(channel)

Pulls a value from a channel. Returns a deferred that resolves either to a successfully pulled value or to undefined in case the channel was closed and contained no buffered value to satisfy the pull.

####close #####csp.close(channel)

Closes a channel. Subsequent pushes will fail. Pulls may succeed until the channel's buffer is exhausted.

####select #####csp.select(operations..., [options])

Performs the first available channel operation from the list of specifications given as arguments, where an options object can be passed in as the last argument. Returns a deferred that resolves to the result of the operation chosen.

A pull operation is specified as a channel by itself, a push as an array of the form [channel, value]. If more than one operation becomes available at the same time, the one executed is chosen at random unless options.priority is true, in which case the one earliest in the argument list is executed. The operation normally 'blocks', i.e., returns a deferred that does not resolve until an operation becomes available. If however, options.default is present, it always resolves immediately and uses the associated value if necessary.

####timeout #####csp.timeout(milliseconds)

####ticker #####csp.ticker(milliseconds)

####each #####csp.each(fn, channel)

####fromGenerator #####csp.fromGenerator(generator, [outChannel])

####createLock #####csp.createLock()

####fromStream #####csp.fromStream(stream, [outChannel, [onOutChannelClosed]])

Clone this wiki locally