Comparing version 2.0.1 to 2.1.0
@@ -16,5 +16,6 @@ /** @license MIT License (c) copyright 2013 original author or authors */ | ||
var when, slice; | ||
var when, promise, slice; | ||
when = require('./when'); | ||
promise = when.promise; | ||
slice = [].slice; | ||
@@ -62,12 +63,10 @@ | ||
return when.all(extraAsyncArgs || []).then(function(args) { | ||
var deferred = when.defer(); | ||
return promise(function(resolve, reject) { | ||
var asyncArgs = args.concat( | ||
alwaysUnary(resolve), | ||
alwaysUnary(reject) | ||
); | ||
var asyncArgs = args.concat( | ||
alwaysUnary(deferred.resolve), | ||
alwaysUnary(deferred.reject) | ||
); | ||
asyncFunction.apply(null, asyncArgs); | ||
return deferred.promise; | ||
asyncFunction.apply(null, asyncArgs); | ||
}); | ||
}); | ||
@@ -195,26 +194,26 @@ } | ||
return when.all(arguments).then(function(args) { | ||
return promise(applyPromisified); | ||
var deferred, callbackPos, errbackPos; | ||
function applyPromisified(resolve, reject) { | ||
var callbackPos, errbackPos; | ||
if('callback' in positions) { | ||
callbackPos = normalizePosition(args, positions.callback); | ||
} | ||
if('callback' in positions) { | ||
callbackPos = normalizePosition(args, positions.callback); | ||
} | ||
if('errback' in positions) { | ||
errbackPos = normalizePosition(args, positions.errback); | ||
} | ||
if('errback' in positions) { | ||
errbackPos = normalizePosition(args, positions.errback); | ||
} | ||
deferred = when.defer(); | ||
if(errbackPos < callbackPos) { | ||
insertCallback(args, errbackPos, reject); | ||
insertCallback(args, callbackPos, resolve); | ||
} else { | ||
insertCallback(args, callbackPos, resolve); | ||
insertCallback(args, errbackPos, reject); | ||
} | ||
if(errbackPos < callbackPos) { | ||
insertCallback(args, errbackPos, deferred.reject); | ||
insertCallback(args, callbackPos, deferred.resolve); | ||
} else { | ||
insertCallback(args, callbackPos, deferred.resolve); | ||
insertCallback(args, errbackPos, deferred.reject); | ||
asyncFunction.apply(null, args); | ||
} | ||
asyncFunction.apply(null, args); | ||
return deferred.promise; | ||
}); | ||
@@ -221,0 +220,0 @@ }; |
@@ -0,1 +1,15 @@ | ||
### 2.1.0 | ||
* New [`when.settle`](docs/api.md#whensettle) that settles an array of promises, regardless of whether the fulfill or reject. | ||
* New [`when/guard`](docs/api.md#whenguard) generalized concurrency guarding and limiting | ||
* New [`promise.inspect`](docs/api.md#inspect) for synchronously getting a snapshot of a promise's state at a particular instant. | ||
* Significant performance improvements when resolving promises with non-primitives (Arrays, Objects, etc.) | ||
* Experimental [vert.x](http://vertx.io) support | ||
* **DEPRECATED**: `onFulfilled`, `onRejected`, `onProgress` handler arguments to `when.all`, `when.any`, `when.some`. Use the returned promise's `then()` (or `otherwise()`, `ensure()`, etc) to register handlers instead. | ||
* For example, do this: `when.all(array).then(onFulfilled, onRejected)` instead of this: `when.all(array, onFulfilled, onRejected)`. The functionality is equivalent. | ||
### 2.0.1 | ||
* Account for the fact that Mocha creates a global named `process`. Thanks [Narsul](https://github.com/cujojs/when/pull/136) | ||
### 2.0.0 | ||
@@ -2,0 +16,0 @@ |
24
debug.js
@@ -38,5 +38,5 @@ /** @license MIT License (c) copyright B Cavalier & J Hann */ | ||
define(function(require) { | ||
/*global vertx,setTimeout*/ | ||
var when, promiseId, pending, exceptionsToRethrow, own, warn, setTimer, undef; | ||
var when, promiseId, pending, exceptionsToRethrow, own, warn, undef; | ||
when = require('./when'); | ||
@@ -51,2 +51,6 @@ promiseId = 0; | ||
setTimer = typeof vertx === 'object' | ||
? function (f, ms) { return vertx.setTimer(ms, f); } | ||
: setTimeout; | ||
exceptionsToRethrow = { | ||
@@ -232,2 +236,6 @@ RangeError: 1, | ||
makeDebugWithHandlers('all', when.all); | ||
makeDebugWithHandlers('any', when.any); | ||
makeDebugWithHandlers('some', when.some, 2); | ||
// For each method we haven't already replaced, replace it with | ||
@@ -250,2 +258,12 @@ // one that sets up debug logging on the returned promise | ||
function makeDebugWithHandlers(name, func, offset) { | ||
makeDebug(name, function() { | ||
offset = offset || 1; | ||
if(typeof arguments[offset] === 'function' || typeof arguments[offset+1] === 'function' || typeof arguments[offset+2] === 'function') { | ||
warn(name + '() onFulfilled, onRejected, and onProgress are deprecated, use returnedPromise.then/otherwise/ensure instead'); | ||
} | ||
return func.apply(when, arguments); | ||
}); | ||
} | ||
// Wrap a promise callback to catch exceptions and log or | ||
@@ -326,3 +344,3 @@ // rethrow as uncatchable | ||
function throwUncatchable(err) { | ||
setTimeout(function() { | ||
setTimer(function() { | ||
throw err; | ||
@@ -329,0 +347,0 @@ }, 0); |
61
delay.js
@@ -1,5 +0,3 @@ | ||
/** @license MIT License (c) copyright B Cavalier & J Hann */ | ||
/** @license MIT License (c) copyright 2011-2013 original author or authors */ | ||
/*global setTimeout:true*/ | ||
/** | ||
@@ -10,3 +8,4 @@ * delay.js | ||
* | ||
* @author brian@hovercraftstudios.com | ||
* @author Brian Cavalier | ||
* @author John Hann | ||
*/ | ||
@@ -16,7 +15,11 @@ | ||
define(function(require) { | ||
/*global vertx,setTimeout*/ | ||
var when, setTimer; | ||
var when, undef; | ||
when = require('./when'); | ||
setTimer = typeof vertx === 'object' | ||
? function (f, ms) { return vertx.setTimer(ms, f); } | ||
: setTimeout; | ||
/** | ||
@@ -26,35 +29,22 @@ * Creates a new promise that will resolve after a msec delay. If promise | ||
* | ||
* Usage: | ||
* // Do something after 1 second, similar to using setTimeout | ||
* delay(1000).then(doSomething); | ||
* // or | ||
* when(delay(1000), doSomething); | ||
* | ||
* // Do something 1 second after triggeringPromise resolves | ||
* delay(triggeringPromise, 1000).then(doSomething, handleRejection); | ||
* // or | ||
* when(delay(triggeringPromise, 1000), doSomething, handleRejection); | ||
* | ||
* @param [promise] anything - any promise or value after which the delay will start | ||
* @param msec {Number} delay in milliseconds | ||
* @param {number} msec delay in milliseconds | ||
* @param {*} [value] any promise or value after which the delay will start | ||
* @returns {Promise} | ||
*/ | ||
return function delay(promise, msec) { | ||
if(arguments.length < 2) { | ||
msec = promise >>> 0; | ||
promise = undef; | ||
} | ||
return function delay(msec, value) { | ||
// Support reversed, deprecated argument ordering | ||
if(typeof value === 'number') { | ||
var tmp = value; | ||
value = msec; | ||
msec = tmp; | ||
} | ||
var deferred = when.defer(); | ||
when(promise, | ||
function(val) { | ||
setTimeout(function() { | ||
deferred.resolve(val); | ||
return when.promise(function(resolve, reject, notify) { | ||
when(value, function(val) { | ||
setTimer(function() { | ||
resolve(val); | ||
}, msec); | ||
}, | ||
deferred.reject, | ||
deferred.notify | ||
); | ||
return deferred.promise; | ||
reject, notify); | ||
}); | ||
}; | ||
@@ -65,5 +55,4 @@ | ||
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); } | ||
// Boilerplate for AMD and Node | ||
); | ||
37
keys.js
@@ -12,5 +12,6 @@ /** @license MIT License (c) copyright 2011-2013 original author or authors */ | ||
define(function(require) { | ||
var when, keys, eachKey, owns; | ||
var when, promise, keys, eachKey, owns; | ||
when = require('./when'); | ||
promise = when.promise; | ||
@@ -66,20 +67,26 @@ // Public API | ||
return when(object, function(object) { | ||
var results, d, toResolve; | ||
return promise(resolveMap); | ||
results = {}; | ||
d = when.defer(); | ||
toResolve = 0; | ||
function resolveMap(resolve, reject, notify) { | ||
var results, toResolve; | ||
eachKey(object, function(value, key) { | ||
++toResolve; | ||
when(value, mapFunc).then(function(mapped) { | ||
results[key] = mapped; | ||
results = {}; | ||
toResolve = 0; | ||
if(!--toResolve) { | ||
d.resolve(results); | ||
} | ||
}, d.reject, d.notify); | ||
}); | ||
eachKey(object, function(value, key) { | ||
++toResolve; | ||
when(value, mapFunc).then(function(mapped) { | ||
results[key] = mapped; | ||
return d.promise; | ||
if(!--toResolve) { | ||
resolve(results); | ||
} | ||
}, reject, notify); | ||
}); | ||
// If there are no keys, resolve immediately | ||
if(!toResolve) { | ||
resolve(results); | ||
} | ||
} | ||
}); | ||
@@ -86,0 +93,0 @@ } |
{ | ||
"name": "when", | ||
"version": "2.0.1", | ||
"version": "2.1.0", | ||
"description": "A lightweight Promises/A+ and when() implementation, plus other async goodies.", | ||
"keywords": ["Promises/A+", "promises-aplus", "promise", "promises", "deferred", "deferreds", "when", "async", "asynchronous", "cujo"], | ||
"homepage": "http://cujojs.com", | ||
"licenses": [ | ||
@@ -29,5 +30,18 @@ { | ||
], | ||
"contributors": [ | ||
{ | ||
"name": "Brian Cavalier", | ||
"web": "http://hovercraftstudios.com" | ||
}, | ||
{ | ||
"name": "John Hann", | ||
"web": "http://unscriptable.com" | ||
}, | ||
{ | ||
"name": "Scott Andrews" | ||
} | ||
], | ||
"devDependencies": { | ||
"curl": "https://github.com/cujojs/curl/tarball/0.7.3", | ||
"test-support": "~0.1", | ||
"test-support": "~0.2", | ||
"promises-aplus-tests": "~1" | ||
@@ -40,3 +54,3 @@ }, | ||
"scripts": { | ||
"test": "jshint . && buster test -e node && promises-aplus-tests test/when-adapter.js", | ||
"test": "jshint . && buster test -e node && promises-aplus-tests test/promises-aplus-adapter.js", | ||
"ci": "npm test && sauceme", | ||
@@ -43,0 +57,0 @@ "start": "buster static -e browser" |
@@ -1,2 +0,2 @@ | ||
/** @license MIT License (c) copyright B Cavalier & J Hann */ | ||
/** @license MIT License (c) copyright 2011-2013 original author or authors */ | ||
@@ -9,3 +9,4 @@ /** | ||
* | ||
* @author brian@hovercraftstudios.com | ||
* @author Brian Cavalier | ||
* @author John Hann | ||
*/ | ||
@@ -16,5 +17,6 @@ | ||
var when; | ||
var when, slice; | ||
when = require('./when'); | ||
slice = Array.prototype.slice; | ||
@@ -30,5 +32,6 @@ /** | ||
return function parallel(tasks /*, args... */) { | ||
var args = Array.prototype.slice.call(arguments, 1); | ||
return when.map(tasks, function(task) { | ||
return task.apply(null, args); | ||
return when.all(slice.call(arguments, 1)).then(function(args) { | ||
return when.map(tasks, function(task) { | ||
return task.apply(null, args); | ||
}); | ||
}); | ||
@@ -35,0 +38,0 @@ }; |
@@ -1,2 +0,2 @@ | ||
/** @license MIT License (c) copyright B Cavalier & J Hann */ | ||
/** @license MIT License (c) copyright 2011-2013 original author or authors */ | ||
@@ -10,3 +10,4 @@ /** | ||
* | ||
* @author brian@hovercraftstudios.com | ||
* @author Brian Cavalier | ||
* @author John Hann | ||
*/ | ||
@@ -17,5 +18,6 @@ | ||
var when; | ||
var when, slice; | ||
when = require('./when'); | ||
slice = Array.prototype.slice; | ||
@@ -31,10 +33,6 @@ /** | ||
return function pipeline(tasks /* initialArgs... */) { | ||
var initialArgs, runTask; | ||
initialArgs = Array.prototype.slice.call(arguments, 1); | ||
// Self-optimizing function to run first task with multiple | ||
// args using apply, but subsequence tasks via direct invocation | ||
runTask = function(task, args) { | ||
runTask = function(task, arg) { | ||
var runTask = function(args, task) { | ||
runTask = function(arg, task) { | ||
return task(arg); | ||
@@ -46,8 +44,7 @@ }; | ||
return when.reduce(tasks, | ||
function(args, task) { | ||
return runTask(task, args); | ||
}, | ||
initialArgs | ||
); | ||
return when.all(slice.call(arguments, 1)).then(function(args) { | ||
return when.reduce(tasks, function(arg, task) { | ||
return runTask(arg, task); | ||
}, args); | ||
}); | ||
}; | ||
@@ -54,0 +51,0 @@ |
@@ -7,6 +7,6 @@ <a href="http://promises-aplus.github.com/promises-spec"><img src="http://promises-aplus.github.com/promises-spec/assets/logo-small.png" alt="Promises/A+ logo" align="right" /></a> | ||
When.js is cujojs's lightweight [Promises/A+](http://promises-aplus.github.com/promises-spec) and `when()` implementation that powers the async core of [wire.js](https://github.com/cujojs/wire), cujojs's IOC Container. It features: | ||
When.js is cujoJS's lightweight [Promises/A+](http://promises-aplus.github.com/promises-spec) and `when()` implementation that powers the async core of [wire.js](https://github.com/cujojs/wire), cujoJS's IOC Container. It features: | ||
* A rock solid, battle-tested Promise implementation | ||
* Resolving, mapping, and reducing arrays of promises | ||
* Resolving, settling, mapping, and reducing arrays of promises | ||
* Executing tasks in parallel and sequence | ||
@@ -19,2 +19,12 @@ * Transforming Node-style and other callback-based APIs into promise-based APIs | ||
### 2.1.0 | ||
* New [`when.settle`](docs/api.md#whensettle) that settles an array of promises | ||
* New [`when/guard`](docs/api.md#whenguard) generalized concurrency guarding and limiting | ||
* New [`promise.inspect`](docs/api.md#inspect) for synchronously getting a snapshot of a promise's state at a particular instant. | ||
* Significant performance improvements when resolving promises with non-primitives (e.g. with Arrays, Objects, etc.) | ||
* Experimental [vert.x](http://vertx.io) support | ||
* **DEPRECATED**: `onFulfilled`, `onRejected`, `onProgress` handler arguments to `when.all`, `when.any`, `when.some`. Use the returned promise's `then()` (or `otherwise()`, `ensure()`, etc) to register handlers instead. | ||
* For example, do this: `when.all(array).then(onFulfilled, onRejected)` instead of this: `when.all(array, onFulfilled, onRejected)`. The functionality is equivalent. | ||
### 2.0.1 | ||
@@ -21,0 +31,0 @@ |
@@ -1,2 +0,2 @@ | ||
/** @license MIT License (c) copyright B Cavalier & J Hann */ | ||
/** @license MIT License (c) copyright 2011-2013 original author or authors */ | ||
@@ -9,3 +9,4 @@ /** | ||
* | ||
* @author brian@hovercraftstudios.com | ||
* @author Brian Cavalier | ||
* @author John Hann | ||
*/ | ||
@@ -16,5 +17,6 @@ | ||
var when; | ||
var when, slice; | ||
when = require('./when'); | ||
slice = Array.prototype.slice; | ||
@@ -30,9 +32,14 @@ /** | ||
return function sequence(tasks /*, args... */) { | ||
var args = Array.prototype.slice.call(arguments, 1); | ||
return when.reduce(tasks, function(results, task) { | ||
return when(task.apply(null, args), function(result) { | ||
results.push(result); | ||
return results; | ||
}); | ||
}, []); | ||
var results = []; | ||
return when.all(slice.call(arguments, 1)).then(function(args) { | ||
return when.reduce(tasks, function(results, task) { | ||
return when(task.apply(null, args), addResult); | ||
}, results); | ||
}); | ||
function addResult(result) { | ||
results.push(result); | ||
return results; | ||
} | ||
}; | ||
@@ -39,0 +46,0 @@ |
@@ -1,5 +0,3 @@ | ||
/** @license MIT License (c) copyright B Cavalier & J Hann */ | ||
/** @license MIT License (c) copyright 2011-2013 original author or authors */ | ||
/*global setTimeout:true, clearTimeout:true*/ | ||
/** | ||
@@ -11,3 +9,4 @@ * timeout.js | ||
* | ||
* @author brian@hovercraftstudios.com | ||
* @author Brian Cavalier | ||
* @author John Hann | ||
*/ | ||
@@ -17,7 +16,15 @@ | ||
define(function(require) { | ||
/*global vertx,setTimeout,clearTimeout*/ | ||
var when, setTimer, cancelTimer; | ||
var when, undef; | ||
when = require('./when'); | ||
if(typeof vertx === 'object') { | ||
setTimer = function (f, ms) { return vertx.setTimer(ms, f); }; | ||
cancelTimer = vertx.cancelTimer; | ||
} else { | ||
setTimer = setTimeout; | ||
cancelTimer = clearTimeout; | ||
} | ||
/** | ||
@@ -27,45 +34,37 @@ * Returns a new promise that will automatically reject after msec if | ||
* | ||
* Usage: | ||
* | ||
* var d = when.defer(); | ||
* // Setup d however you need | ||
* | ||
* // return a new promise that will timeout if d doesn't resolve/reject first | ||
* return timeout(d.promise, 1000); | ||
* | ||
* @param promise anything - any promise or value that should trigger | ||
* the returned promise to resolve or reject before the msec timeout | ||
* @param msec {Number} timeout in milliseconds | ||
* | ||
* @param {number} msec timeout in milliseconds | ||
* @param {*} trigger - any promise or value that should trigger the | ||
* returned promise to resolve or reject before the msec timeout | ||
* @returns {Promise} | ||
*/ | ||
return function timeout(promise, msec) { | ||
var deferred, timeoutRef; | ||
return function timeout(msec, trigger) { | ||
var timeoutRef, rejectTimeout; | ||
deferred = when.defer(); | ||
// Support reversed, deprecated argument ordering | ||
if(typeof trigger === 'number') { | ||
var tmp = trigger; | ||
trigger = msec; | ||
msec = tmp; | ||
} | ||
timeoutRef = setTimeout(function onTimeout() { | ||
timeoutRef && deferred.reject(new Error('timed out')); | ||
timeoutRef = setTimer(function onTimeout() { | ||
rejectTimeout(new Error('timed out after ' + msec + 'ms')); | ||
}, msec); | ||
function cancelTimeout() { | ||
clearTimeout(timeoutRef); | ||
timeoutRef = undef; | ||
} | ||
return when.promise(function(resolve, reject, notify) { | ||
rejectTimeout = reject; // capture, tricky | ||
when(promise, | ||
function(value) { | ||
cancelTimeout(); | ||
deferred.resolve(value); | ||
}, | ||
function(reason) { | ||
cancelTimeout(); | ||
deferred.reject(reason); | ||
}, | ||
deferred.notify | ||
); | ||
return deferred.promise; | ||
when(trigger, | ||
function onFulfill(value) { | ||
cancelTimer(timeoutRef); | ||
resolve(value); | ||
}, | ||
function onReject(reason) { | ||
cancelTimer(timeoutRef); | ||
reject(reason); | ||
}, | ||
notify | ||
); | ||
}); | ||
}; | ||
}); | ||
@@ -72,0 +71,0 @@ })( |
219
when.js
@@ -12,5 +12,5 @@ /** @license MIT License (c) copyright 2011-2013 original author or authors */ | ||
* @author John Hann | ||
* @version 2.0.1 | ||
* @version 2.1.0 | ||
*/ | ||
(function(define) { 'use strict'; | ||
(function(define, global) { 'use strict'; | ||
define(function () { | ||
@@ -29,2 +29,3 @@ | ||
when.reduce = reduce; // Array.reduce() for promises | ||
when.settle = settle; // Settle a list of promises | ||
@@ -36,2 +37,4 @@ when.any = any; // One-winner race | ||
when.promise = promise; // EXPERIMENTAL: May change. Use at your own risk | ||
/** | ||
@@ -65,4 +68,5 @@ * Register an observer for a promise or immediate value. | ||
*/ | ||
function Promise(then) { | ||
function Promise(then, inspect) { | ||
this.then = then; | ||
this.inspect = inspect; | ||
} | ||
@@ -91,6 +95,4 @@ | ||
ensure: function(onFulfilledOrRejected) { | ||
var self = this; | ||
return this.then(injectHandler, injectHandler).yield(this); | ||
return this.then(injectHandler, injectHandler).yield(self); | ||
function injectHandler() { | ||
@@ -177,2 +179,5 @@ return resolve(onFulfilledOrRejected()); | ||
* promise: Promise, | ||
* resolve: function:Promise, | ||
* reject: function:Promise, | ||
* notify: function:Promise | ||
* resolver: { | ||
@@ -240,3 +245,3 @@ * resolve: function:Promise, | ||
// Return the promise | ||
return new Promise(then); | ||
return new Promise(then, inspect); | ||
@@ -266,2 +271,6 @@ /** | ||
function inspect() { | ||
return value ? value.inspect() : toPendingState(); | ||
} | ||
/** | ||
@@ -316,3 +325,5 @@ * Transition from pre-resolution state to post-resolution state, notifying | ||
return x; | ||
} else if (x !== Object(x)) { | ||
} | ||
if (!(x === Object(x) && 'then' in x)) { | ||
return fulfilled(x); | ||
@@ -357,2 +368,4 @@ } | ||
} | ||
}, function() { | ||
return toFulfilledState(value); | ||
}); | ||
@@ -377,2 +390,4 @@ | ||
} | ||
}, function() { | ||
return toRejectedState(reason); | ||
}); | ||
@@ -437,5 +452,5 @@ | ||
* @param howMany {number} number of promisesOrValues to resolve | ||
* @param {function?} [onFulfilled] resolution handler | ||
* @param {function?} [onRejected] rejection handler | ||
* @param {function?} [onProgress] progress handler | ||
* @param {function?} [onFulfilled] DEPRECATED, use returnedPromise.then() | ||
* @param {function?} [onRejected] DEPRECATED, use returnedPromise.then() | ||
* @param {function?} [onProgress] DEPRECATED, use returnedPromise.then() | ||
* @returns {Promise} promise that will resolve to an array of howMany values that | ||
@@ -447,4 +462,2 @@ * resolved first, or will reject with an array of | ||
checkCallbacks(2, arguments); | ||
return when(promisesOrValues, function(promisesOrValues) { | ||
@@ -473,3 +486,3 @@ | ||
if(!--toReject) { | ||
fulfillOne = rejectOne = noop; | ||
fulfillOne = rejectOne = identity; | ||
reject(reasons); | ||
@@ -483,3 +496,3 @@ } | ||
if (!--toResolve) { | ||
fulfillOne = rejectOne = noop; | ||
fulfillOne = rejectOne = identity; | ||
resolve(values); | ||
@@ -514,5 +527,5 @@ } | ||
* of {@link Promise}s and values | ||
* @param {function?} [onFulfilled] resolution handler | ||
* @param {function?} [onRejected] rejection handler | ||
* @param {function?} [onProgress] progress handler | ||
* @param {function?} [onFulfilled] DEPRECATED, use returnedPromise.then() | ||
* @param {function?} [onRejected] DEPRECATED, use returnedPromise.then() | ||
* @param {function?} [onProgress] DEPRECATED, use returnedPromise.then() | ||
* @returns {Promise} promise that will resolve to the value that resolved first, or | ||
@@ -538,10 +551,9 @@ * will reject with an array of all rejected inputs. | ||
* of {@link Promise}s and values | ||
* @param {function?} [onFulfilled] resolution handler | ||
* @param {function?} [onRejected] rejection handler | ||
* @param {function?} [onProgress] progress handler | ||
* @param {function?} [onFulfilled] DEPRECATED, use returnedPromise.then() | ||
* @param {function?} [onRejected] DEPRECATED, use returnedPromise.then() | ||
* @param {function?} [onProgress] DEPRECATED, use returnedPromise.then() | ||
* @returns {Promise} | ||
*/ | ||
function all(promisesOrValues, onFulfilled, onRejected, onProgress) { | ||
checkCallbacks(1, arguments); | ||
return map(promisesOrValues, identity).then(onFulfilled, onRejected, onProgress); | ||
return _map(promisesOrValues, identity).then(onFulfilled, onRejected, onProgress); | ||
} | ||
@@ -555,18 +567,39 @@ | ||
function join(/* ...promises */) { | ||
return map(arguments, identity); | ||
return _map(arguments, identity); | ||
} | ||
/** | ||
* Traditional map function, similar to `Array.prototype.map()`, but allows | ||
* input to contain {@link Promise}s and/or values, and mapFunc may return | ||
* either a value or a {@link Promise} | ||
* | ||
* @param {Array|Promise} array array of anything, may contain a mix | ||
* of {@link Promise}s and values | ||
* @param {function} mapFunc mapping function mapFunc(value) which may return | ||
* either a {@link Promise} or value | ||
* @returns {Promise} a {@link Promise} that will resolve to an array containing | ||
* the mapped output values. | ||
* Settles all input promises such that they are guaranteed not to | ||
* be pending once the returned promise fulfills. The returned promise | ||
* will always fulfill, except in the case where `array` is a promise | ||
* that rejects. | ||
* @param {Array|Promise} array or promise for array of promises to settle | ||
* @returns {Promise} promise that always fulfills with an array of | ||
* outcome snapshots for each input promise. | ||
*/ | ||
function settle(array) { | ||
return _map(array, toFulfilledState, toRejectedState); | ||
} | ||
/** | ||
* Promise-aware array map function, similar to `Array.prototype.map()`, | ||
* but input array may contain promises or values. | ||
* @param {Array|Promise} array array of anything, may contain promises and values | ||
* @param {function} 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(array, mapFunc) { | ||
return _map(array, mapFunc); | ||
} | ||
/** | ||
* Internal map that allows a fallback to handle rejections | ||
* @param {Array|Promise} array array of anything, may contain promises and values | ||
* @param {function} mapFunc map function which may return a promise or value | ||
* @param {function?} fallback function to handle rejected promises | ||
* @returns {Promise} promise that will fulfill with an array of mapped values | ||
* or reject if any input promise rejects. | ||
*/ | ||
function _map(array, mapFunc, fallback) { | ||
return when(array, function(array) { | ||
@@ -586,21 +619,21 @@ | ||
resolve(results); | ||
} else { | ||
return; | ||
} | ||
resolveOne = function(item, i) { | ||
when(item, mapFunc).then(function(mapped) { | ||
results[i] = mapped; | ||
resolveOne = function(item, i) { | ||
when(item, mapFunc, fallback).then(function(mapped) { | ||
results[i] = mapped; | ||
if(!--toResolve) { | ||
resolve(results); | ||
} | ||
}, reject, notify); | ||
}; | ||
if(!--toResolve) { | ||
resolve(results); | ||
} | ||
}, reject, notify); | ||
}; | ||
// Since mapFunc may be async, get all invocations of it into flight | ||
for(i = 0; i < len; i++) { | ||
if(i in array) { | ||
resolveOne(array[i], i); | ||
} else { | ||
--toResolve; | ||
} | ||
// Since mapFunc may be async, get all invocations of it into flight | ||
for(i = 0; i < len; i++) { | ||
if(i in array) { | ||
resolveOne(array[i], i); | ||
} else { | ||
--toResolve; | ||
} | ||
@@ -647,2 +680,33 @@ } | ||
// Snapshot states | ||
/** | ||
* Creates a fulfilled state snapshot | ||
* @private | ||
* @param {*} x any value | ||
* @returns {{state:'fulfilled',value:*}} | ||
*/ | ||
function toFulfilledState(x) { | ||
return { state: 'fulfilled', value: x }; | ||
} | ||
/** | ||
* Creates a rejected state snapshot | ||
* @private | ||
* @param {*} x any reason | ||
* @returns {{state:'rejected',reason:*}} | ||
*/ | ||
function toRejectedState(x) { | ||
return { state: 'rejected', reason: x }; | ||
} | ||
/** | ||
* Creates a pending state snapshot | ||
* @private | ||
* @returns {{state:'pending'}} | ||
*/ | ||
function toPendingState() { | ||
return { state: 'pending' }; | ||
} | ||
// | ||
@@ -653,3 +717,3 @@ // Utilities, etc. | ||
var reduceArray, slice, fcall, nextTick, handlerQueue, | ||
timeout, funcProto, call, arrayProto, undef; | ||
setTimeout, funcProto, call, arrayProto, undef; | ||
@@ -677,3 +741,3 @@ // | ||
/** | ||
* Schedule the queue to be drained in the next tick. | ||
* Schedule the queue to be drained after the stack has cleared. | ||
*/ | ||
@@ -685,4 +749,4 @@ function scheduleDrainQueue() { | ||
/** | ||
* Drain the handler queue entirely or partially, being careful to allow | ||
* the queue to be extended while it is being processed, and to continue | ||
* Drain the handler queue entirely, being careful to allow the | ||
* queue to be extended while it is being processed, and to continue | ||
* processing until it is truly empty. | ||
@@ -703,13 +767,11 @@ */ | ||
// | ||
/*global setTimeout,setImmediate,window,process*/ | ||
/*global setImmediate,process,vertx*/ | ||
// capture setTimeout to avoid being caught by fake timers used in time based tests | ||
timeout = setTimeout; | ||
nextTick = typeof setImmediate === 'function' | ||
? typeof window === 'undefined' | ||
? setImmediate | ||
: setImmediate.bind(window) | ||
: typeof process === 'object' && process.nextTick | ||
? process.nextTick | ||
: function(task) { timeout(task, 0); }; | ||
setTimeout = global.setTimeout; | ||
// Prefer setImmediate, cascade to node, vertx and finally setTimeout | ||
nextTick = typeof setImmediate === 'function' ? setImmediate.bind(global) | ||
: typeof process === 'object' && process.nextTick ? process.nextTick | ||
: typeof vertx === 'object' ? vertx.runOnLoop // vert.x | ||
: function(task) { setTimeout(task, 0); }; // fallback | ||
@@ -775,30 +837,2 @@ // Safe function calls | ||
// | ||
// Utility functions | ||
// | ||
/** | ||
* Helper that checks arrayOfCallbacks to ensure that each element is either | ||
* a function, or null or undefined. | ||
* @private | ||
* @param {number} start index at which to start checking items in arrayOfCallbacks | ||
* @param {Array} arrayOfCallbacks array to check | ||
* @throws {Error} if any element of arrayOfCallbacks is something other than | ||
* a functions, null, or undefined. | ||
*/ | ||
function checkCallbacks(start, arrayOfCallbacks) { | ||
// TODO: Promises/A+ update type checking and docs | ||
var arg, i = arrayOfCallbacks.length; | ||
while(i > start) { | ||
arg = arrayOfCallbacks[--i]; | ||
if (arg != null && typeof arg != 'function') { | ||
throw new Error('arg '+i+' must be a function'); | ||
} | ||
} | ||
} | ||
function noop() {} | ||
function identity(x) { | ||
@@ -811,3 +845,4 @@ return x; | ||
})( | ||
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(); } | ||
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(); }, | ||
this | ||
); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
96447
25
2301
2
0
119