Covenant
Covenant is a fully compliant Promises/A+ implementation written in Coffeescript. Covenant, its core class is a bare-bones implementation that passes the Promises/A+ Test Suite, as well as the present draft of version 1.1 of the test suite. Covenant's core is very performant and extremely lightweight.
The Covenant (Core) API
require'covenant' # create a new promise, which can be figured using subsequent # subsequent calls to the fulfill, reject and resolve methods p = # the promise can be configured with a callback function, which # will be passed a resolution and rejection function, as well as # a reference to the promise itself. Also, `this` is set to reference # the promise. pDelay50ms = setTimeout -> resolve'50 milliseconds have passed'50 # fulfill the promise with a value pfulfillvalue # reject the promise with a reason prejectreason # Wrap another promise or foreign "thennable" and adopt its state. # Otherwise, fulfill with the value or reject if unable to adopt. # Works with Promise/A+-conforming and many non-conforming promises. presolvepromiseThennableOrValue # schedule asynchronous handlers, as often as you like, before or after resolution # the handler may be a value, a function or a promise (an object having a function # property named "then." covenantthen onFulfilledonRejected # A Covenant object with a single `then` method linked to the promise. # The promise can be passed to a client authorized to schedule callbacks # on the Core object, but will not be able to change its state. ppromise
The Promise (Extended) API
Promise, more full-featured extension of Covenant's core is included, although it is in pre-alpha form at this time. It provides: a nice collection of promise-generating operations, an aggregation function, some convenience functions and functions for securely sharing promise objects with clients for limited use.
Promise Generation Functions
require 'promise' # Promise.pending(): construct a pending promise p = Promisepending anythingconsolelog # => nothing yet! fulfill"I'm all done" # => I'm all done" # Promise.fulfilled(value): construct a promise fulfilled with value Promisefulfilled42 doneconsolelog # => 43 # Promise.rejected(reason): construct a promise rejected for reason Promiserejected"naughty you" failconsoleerror # => "naughty you" # Promise.fromNode(nodeOperation): construct a promise generating function based on node functions f = PromisefromNodefsreadFilepReadFile = f'foo.data' # construct a promise that fulfills after ms milliseconds Promisedelay100 # construct a promise that rejects for timeout unless resolved before ms milliseconds. Promisetimeoutp100
Aggregate Promise Functions
# Promise.when(promiseOrValueList): Construct a promise from any number of values or promises, which fulfills with an # array of corresponding values if all promises are fulfilled, and rejects if ANY # example when promise is rejected # with raw values Promisewhen123 done consolelog # => [1, 2, 3] # with pending promises, ultimately fulfilled p = Promisependingq = Promisewhen p2Promisefulfilled3qdone consolelog # => nothing happens pfulfill1 # => [1,2,3] after a tick or two # with pending promises, one rejectedl PromisewhenPromisependingPromisefulfilled2Promiserejected"Error in 3" failconsoleerror # => Error in 3 p = Promisewhen p1p2p3failconsoleerror # => Error in 3 # Promise.all(valueOrPromiseList): same as Promise.all Promise.when
Promise Instance Convenience Functions
# p.done(callback): convenience function for p.then onFulfill, undefined pdoneonFulfill # p.fail(callback): convenience function for p.then undefined, onReject pfailonReject # p.always(callback): convenience function for p.then callback, callback palwayscallback # Note that the promise returned by p.always(callback) can resolve # differently, even when p has already resolved.
Installation
Download it, clone it, or npm install wizardwerdna/covenant
Covenant has no dependencies, but does use process.nextTick, found in modern Browsers. If process.nextTick is not a function, Covenant falls back to setImmediate, and then to setTimeout. If you are using ancient browsers, it is highly recommended that you use a shim to implement (fake) nextTick and/or setImmediate.
Credits
I am indebted, in particular, to the work of Brian Cavalier, whose when.js, and avow.js libraries illuminate what can be done both in a full-featured and minimalist implementation.
Running the tests
- clone the respository
npm install
npm test
npm run-script browserTest
The browser test will run the tests directly on Safari, Chrome, Firefox and phantomJS.
Some configuration of karma.conf.js
will be necessary if you haven't configured one
or more of the browsers. phantomJS was installed when you ran npm install
.
License
MIT License, Copyright (c) 2013 Andrew C. Greenberg (wizardwerdna@gmail.com)