Oath.js

Welcome

Oath.js is a utility toolbelt for working with Promises in JavaScript. It can accept any Promises/A+-compliant promise object to any one of its methods.

Travis CI Build

Find out more about Oath in the Github repository. Contributions are welcome.

Documentation

Using Oath

Oath is simple enough to use. First, make sure Oath is installed:

npm install oathjs

From your JavaScript, you can include Oath by simple require()ing it:

var oath = require('oathjs');

Arguments

Some methods, like all(), accept only an array of promises. For any of these methods, either of the following two options are available:

  1. An array of promises is accepted as the first argument.
  2. An indefinite number of arguments are accepted, where each argument is a single promise.

all()

This method is a pass-through to the specced Promise.all() method. It accepts an array of promises. If all of the promises resolve, this method will resolve with an array containing the fulfilled values of each of the promises. If any of the promises reject, this method will reject with the reason provided by the first promise to reject.

always()

This method accepts one argument:

When the passed promise resolves, this method will resolve with the passed promise's fulfilled value. When the passed promise rejects, this method will resolve with the passed promise's rejection reason.

any()

This method is the opposite of all(). It accepts an array of promises. When any of the passed promises resolve, this method will resolve with the value provided by the passed promise. If all of the passed promises reject, this method will reject.

Note that this method is different from first() in that it will not reject when the first passed promise rejects. Instead, it will only reject when all passed promises reject.

CancellablePromise()

var request = new oath.CancellablePromise(function(resolve, reject, cancelCallback) {
    var xhr = require('xhr').get(url);
    xhr.onload = resolve;
    xhr.onerror = reject;
    cancelCallback(xhr.abort, xhr); // Second argument is context
});

var timeout = setTimeout(request.cancel, 30000);
oath.always(request).then(clearTimeout.bind(null, timeout));

A cancellable promise is a promise that can be "turned off". It extends a normal promise, having identical behavior, except it has a cancel() method. This method, when called, will cause the reject and resolve methods of the promise to noop.

Additionally, a third argument is passed to the promise's handler. This third argument is a function that can be called to set handlers for cancellation. When the promise is cancelled, each of the functions passed to the cancellation callback will be fired in the order that they were passed. An optional second argument can be provided for context.

Cancellable promises can only be cancelled a single time. If the promise is not pending, it cannot be cancelled.

filter()

filter() accepts three arguments:

After each of the promises passed in arr resolves, the fulfilled value of each promise will be passed to iterator. If iterator returns false for any input, the value returned by the corresponding promise will be excluded from the final fulfilled value of the method. When all passed promises have resolved, the method will resolve with an array containing all values which iterator returned a truthy value for. The order of the values relative to their respective promises is preserved.

If any of the passed promises reject, the method will reject.

first()

oath.first(
    pingHostname1(),
    pingHostname2(),
    pingHostname3()
).then(function(hostname) {
    console.log(hostname + ' is the fastest');
}, function() {
    console.warn('The connection may be flaky');
});

Aliased to race(), as well.

This method accepts an array of promises. When any passed promise resolves or rejects, this method will resolve or reject with the same value or reason.

ignore()

setUpEnvironment().then(
    // Ignore promises that reject
    oath.ignore(
        tryToRefreshEmail(),
        updateRSSFeeds(),
        downloadNewCalendarEvents()
    )
).then(unlockUI);

This method accepts an array of promises. Rejected promises are ignored. When all passed promises have either resolved or rejected, this method will resolve with an array containing all fulfilled values of each of the passed promises that resolved. The relative ordering of the values is preserved.

map()

oath.map(
    [getPublicPosts(), getPrivatePosts(), getFriendsPosts()],
    function(posts) {
        // This will be called immediately for each passed promise
        // rather than after all promises have resolved.
        return posts.postData;
    }
).then(processAllPostData);

map() accepts three arguments:

If any of the passed promises reject, the method will reject with the passed promise's reason for rejection.

Functionally, map() will behave in the following way:

Promise.all(arr).map(iterator, context);

The difference, however, is two-fold:

  1. iterator can return promises.
  2. map() will process iterator as soon as each of the passed promises resolve, resulting in improved performance.

The improved performance is due to the fact that the mapping process does not need to wait until all of the passed promises resolve. Instead, the fulfilled values are processed immediately and concurrently. This is especially true with asynchronous APIs.

rateLimit()

oath.rateLimit(2, [
    uploadFile('favicon.ico'),
    uploadFile('nope.gif'),
    uploadFile('oh_snap.jpg'),
    uploadFile('trololo.mp3')
]).then(function() {
    console.log('upload complete');
});

rateLimit() accepts three arguments:

When called, rateLimit will shift closures from arr until limit has been reached. At that point, it will wait for the executing promises to resolve. When one or more of the promises resolve, the process of shifting closures will continue until all closures have been processed.

If any promise returned by a closure rejects, it will be ignored unless rejectShouldAbort is truthy. If rejectShouldAbort is truthy, the rejection reason of the rejected promise will be passed as the rejection reason for rateLimit.