Promises/A
STATUS: Proposal by KrisZyp
Contents
Proposal
A promise represents the eventual value returned from the single completion of an operation. A promise may be in one of the three states, unfulfilled, fulfilled, and failed. The promise may only move from unfulfilled to fulfilled, or unfulfilled to failed. Once a promise is fulfilled or failed, the promise's value MUST not be changed, just as a values in JavaScript, primitives and object identities, can not change (although objects themselves may always be mutable even if their identity isn't). The immutable characteristic of promises are important for avoiding side-effects from listeners that can create unanticipated changes in behavior and allows promises to be passed to other functions without affecting the caller, in same way that primitives can be passed to functions without any concern that the caller's variable will be modified by the callee.
This API does not define how promises are created, but only defines the necessary interface that a promise must provide for promise consumers to interact with it. Implementors are free to define how promises are generated. Some promises may be provide their own functions to fulfill the promise, and other promises may be fulfilled by mechanisms that are not visible to the promise consumer. See the [Promise Manager] API for a proposal for useful convenience functions. Promises itself may include other additional convenience methods as well. For example, one could implement Dojo's Deferred functions on promises such as addCallback and addBoth.
A promise is defined as an object that has a function as the value for the property 'then':
- then(fulfilledHandler, errorHandler, progressHandler)
- Adds a fulfilledHandler, errorHandler, and progressHandler to be called for completion of a promise. The fulfilledHandler is called when the promise is fulfilled. The errorHandler is called when a promise fails. The progressHandler is called for progress events. All arguments are optional and non-function values are ignored. The progressHandler is not only an optional argument, but progress events are purely optional. Promise implementors are not required to ever call a progressHandler (the progressHandler may be ignored), this parameter exists so that implementors may call it if they have progress events to report.
This function should return a new promise that is fulfilled when the given fulfilledHandler or errorHandler callback is finished. This allows promise operations to be chained together. The value returned from the callback handler is the fulfillment value for the returned promise. If the callback throws an error, the returned promise will be moved to failed state.
An example of using a CommonJS compliant promise:
>asyncComputeTheAnswerToEverything(). then(addTwo). then(printResult, onError); 44
An interactive-promise is an extended promise that supports the following additional functions:
- get(propertyName)
- Requests the given property from the target of this promise. Returns a promise to provide the value of the stated property from this promise's target.
- call(functionName, arg1, arg2, ...)
- Request to call the given method/function on the target of this promise. Returns a promise to provide the return value of the requested function call.
Open Issues
Should calls to the callback handlers be put on the event queue or executed immediately? - Currently unspecified, and I don't know for sure what is best.
Implementations
Tests
- domenic/promise-tests A test suite for CommonJS Promises/A
Libraries
- Q Works in both NodeJS and browsers, compatible with jQuery, thenable, and usable as remote objects via message passing
- RSVP.js A lightweight library that provides tools for organizing asynchronous code
- when.js Compact promises with joining and chaining
- node-promise Promises for NodeJS
- jQuery 1.5 is said to be 'based on the CommonJS Promises/A design'.
- ForbesLindesay/promises-a A bare bones implementation of Promises/A intended to pass https://github.com/domenic/promise-tests while being as small as possible
- WinJS / Windows 8 / Metro
Other
- Q-IO Interfaces for IO using Q promises in JavaScript on Node
- Q-Connection A JavaScript library for communicating asynchronously with remote objects using promises.
- Promised-IO Promised I/O for multiple platforms (developed as a dependency of Perstore)
- WebDriverJs JavaScript bindings for WebDriver, uses promises.
- mocha-as-promised Adds “thenable” promise support to the Mocha test runner.
- dynamo-as-promised A promise-based client for Amazon's DynamoDB.
- chai-as-promised Extends Chai with assertions about promises.
- Joey An HTTP content negotiation client and server JavaScript library, inspired by Sinatra and JSGI, and using Q promises.
- Mr A CommonJS module system for front-end web application development
Deprecated
- http://github.com/280north/narwhal/blob/master/lib/promise.js Promises for Narwhal
- http://github.com/280north/narwhal/blob/master/lib/events.js Experimental Promises on Emitters