You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
8.0 KiB
229 lines
8.0 KiB
/** @license MIT License (c) copyright 2010-2014 original author or authors */ |
|
|
|
/** |
|
* Promises/A+ and when() implementation |
|
* when is part of the cujoJS family of libraries (http://cujojs.com/) |
|
* @author Brian Cavalier |
|
* @author John Hann |
|
* @version 3.6.4 |
|
*/ |
|
(function(define) { 'use strict'; |
|
define(function (require) { |
|
|
|
var timed = require('./lib/decorators/timed'); |
|
var array = require('./lib/decorators/array'); |
|
var flow = require('./lib/decorators/flow'); |
|
var fold = require('./lib/decorators/fold'); |
|
var inspect = require('./lib/decorators/inspect'); |
|
var generate = require('./lib/decorators/iterate'); |
|
var progress = require('./lib/decorators/progress'); |
|
var withThis = require('./lib/decorators/with'); |
|
var unhandledRejection = require('./lib/decorators/unhandledRejection'); |
|
var TimeoutError = require('./lib/TimeoutError'); |
|
|
|
var Promise = [array, flow, fold, generate, progress, |
|
inspect, withThis, timed, unhandledRejection] |
|
.reduce(function(Promise, feature) { |
|
return feature(Promise); |
|
}, require('./lib/Promise')); |
|
|
|
var apply = require('./lib/apply')(Promise); |
|
|
|
// Public API |
|
|
|
when.promise = promise; // Create a pending promise |
|
when.resolve = Promise.resolve; // Create a resolved promise |
|
when.reject = Promise.reject; // Create a rejected promise |
|
|
|
when.lift = lift; // lift a function to return promises |
|
when['try'] = attempt; // call a function and return a promise |
|
when.attempt = attempt; // alias for when.try |
|
|
|
when.iterate = Promise.iterate; // DEPRECATED (use cujojs/most streams) Generate a stream of promises |
|
when.unfold = Promise.unfold; // DEPRECATED (use cujojs/most streams) Generate a stream of promises |
|
|
|
when.join = join; // Join 2 or more promises |
|
|
|
when.all = all; // Resolve a list of promises |
|
when.settle = settle; // Settle a list of promises |
|
|
|
when.any = lift(Promise.any); // One-winner race |
|
when.some = lift(Promise.some); // Multi-winner race |
|
when.race = lift(Promise.race); // First-to-settle race |
|
|
|
when.map = map; // Array.map() for promises |
|
when.filter = filter; // Array.filter() for promises |
|
when.reduce = lift(Promise.reduce); // Array.reduce() for promises |
|
when.reduceRight = lift(Promise.reduceRight); // Array.reduceRight() for promises |
|
|
|
when.isPromiseLike = isPromiseLike; // Is something promise-like, aka thenable |
|
|
|
when.Promise = Promise; // Promise constructor |
|
when.defer = defer; // Create a {promise, resolve, reject} tuple |
|
|
|
// Error types |
|
|
|
when.TimeoutError = TimeoutError; |
|
|
|
/** |
|
* Get a trusted promise for x, or by transforming x with onFulfilled |
|
* |
|
* @param {*} x |
|
* @param {function?} onFulfilled callback to be called when x is |
|
* successfully fulfilled. If promiseOrValue is an immediate value, callback |
|
* will be invoked immediately. |
|
* @param {function?} onRejected callback to be called when x is |
|
* rejected. |
|
* @param {function?} onProgress callback to be called when progress updates |
|
* are issued for x. @deprecated |
|
* @returns {Promise} a new promise that will fulfill with the return |
|
* value of callback or errback or the completion value of promiseOrValue if |
|
* callback and/or errback is not supplied. |
|
*/ |
|
function when(x, onFulfilled, onRejected, onProgress) { |
|
var p = Promise.resolve(x); |
|
if (arguments.length < 2) { |
|
return p; |
|
} |
|
|
|
return p.then(onFulfilled, onRejected, onProgress); |
|
} |
|
|
|
/** |
|
* Creates a new promise whose fate is determined by resolver. |
|
* @param {function} resolver function(resolve, reject, notify) |
|
* @returns {Promise} promise whose fate is determine by resolver |
|
*/ |
|
function promise(resolver) { |
|
return new Promise(resolver); |
|
} |
|
|
|
/** |
|
* Lift the supplied function, creating a version of f that returns |
|
* promises, and accepts promises as arguments. |
|
* @param {function} f |
|
* @returns {Function} version of f that returns promises |
|
*/ |
|
function lift(f) { |
|
return function() { |
|
for(var i=0, l=arguments.length, a=new Array(l); i<l; ++i) { |
|
a[i] = arguments[i]; |
|
} |
|
return apply(f, this, a); |
|
}; |
|
} |
|
|
|
/** |
|
* Call f in a future turn, with the supplied args, and return a promise |
|
* for the result. |
|
* @param {function} f |
|
* @returns {Promise} |
|
*/ |
|
function attempt(f /*, args... */) { |
|
/*jshint validthis:true */ |
|
for(var i=0, l=arguments.length-1, a=new Array(l); i<l; ++i) { |
|
a[i] = arguments[i+1]; |
|
} |
|
return apply(f, this, a); |
|
} |
|
|
|
/** |
|
* Creates a {promise, resolver} pair, either or both of which |
|
* may be given out safely to consumers. |
|
* @return {{promise: Promise, resolve: function, reject: function, notify: function}} |
|
*/ |
|
function defer() { |
|
return new Deferred(); |
|
} |
|
|
|
function Deferred() { |
|
var p = Promise._defer(); |
|
|
|
function resolve(x) { p._handler.resolve(x); } |
|
function reject(x) { p._handler.reject(x); } |
|
function notify(x) { p._handler.notify(x); } |
|
|
|
this.promise = p; |
|
this.resolve = resolve; |
|
this.reject = reject; |
|
this.notify = notify; |
|
this.resolver = { resolve: resolve, reject: reject, notify: notify }; |
|
} |
|
|
|
/** |
|
* Determines if x is promise-like, i.e. a thenable object |
|
* NOTE: Will return true for *any thenable object*, and isn't truly |
|
* safe, since it may attempt to access the `then` property of x (i.e. |
|
* clever/malicious getters may do weird things) |
|
* @param {*} x anything |
|
* @returns {boolean} true if x is promise-like |
|
*/ |
|
function isPromiseLike(x) { |
|
return x && typeof x.then === 'function'; |
|
} |
|
|
|
/** |
|
* Return a promise that will resolve only once all the supplied arguments |
|
* have resolved. The resolution value of the returned promise will be an array |
|
* containing the resolution values of each of the arguments. |
|
* @param {...*} arguments may be a mix of promises and values |
|
* @returns {Promise} |
|
*/ |
|
function join(/* ...promises */) { |
|
return Promise.all(arguments); |
|
} |
|
|
|
/** |
|
* Return a promise that will fulfill once all input promises have |
|
* fulfilled, or reject when any one input promise rejects. |
|
* @param {array|Promise} promises array (or promise for an array) of promises |
|
* @returns {Promise} |
|
*/ |
|
function all(promises) { |
|
return when(promises, Promise.all); |
|
} |
|
|
|
/** |
|
* Return a promise that will always fulfill with an array containing |
|
* the outcome states of all input promises. The returned promise |
|
* will only reject if `promises` itself is a rejected promise. |
|
* @param {array|Promise} promises array (or promise for an array) of promises |
|
* @returns {Promise} promise for array of settled state descriptors |
|
*/ |
|
function settle(promises) { |
|
return when(promises, Promise.settle); |
|
} |
|
|
|
/** |
|
* Promise-aware array map function, similar to `Array.prototype.map()`, |
|
* but input array may contain promises or values. |
|
* @param {Array|Promise} promises array of anything, may contain promises and values |
|
* @param {function(x:*, index:Number):*} mapFunc map function which may |
|
* return a promise or value |
|
* @returns {Promise} promise that will fulfill with an array of mapped values |
|
* or reject if any input promise rejects. |
|
*/ |
|
function map(promises, mapFunc) { |
|
return when(promises, function(promises) { |
|
return Promise.map(promises, mapFunc); |
|
}); |
|
} |
|
|
|
/** |
|
* Filter the provided array of promises using the provided predicate. Input may |
|
* contain promises and values |
|
* @param {Array|Promise} promises array of promises and values |
|
* @param {function(x:*, index:Number):boolean} predicate filtering predicate. |
|
* Must return truthy (or promise for truthy) for items to retain. |
|
* @returns {Promise} promise that will fulfill with an array containing all items |
|
* for which predicate returned truthy. |
|
*/ |
|
function filter(promises, predicate) { |
|
return when(promises, function(promises) { |
|
return Promise.filter(promises, predicate); |
|
}); |
|
} |
|
|
|
return when; |
|
}); |
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
|
|
|