Socket
Socket
Sign inDemoInstall

when

Package Overview
Dependencies
Maintainers
1
Versions
63
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

when - npm Package Compare versions

Comparing version 2.8.0 to 3.0.0

es6-shim/Promise.browserify-es6.js

3

bower.json
{
"name": "when",
"version": "3.0.0",
"main": "when.js",
"version": "2.8.0",
"moduleType": ["amd", "node"],
"description": "A lightweight Promises/A+ and when() implementation, plus other async goodies.",

@@ -6,0 +7,0 @@ "keywords": ["Promises/A+", "promises-aplus", "promise", "promises", "deferred", "deferreds", "when", "async", "asynchronous", "cujo"],

@@ -1,10 +0,8 @@

/** @license MIT License (c) copyright 2013 original author or authors */
/** @license MIT License (c) copyright 2013-2014 original author or authors */
/**
* callbacks.js
*
* Collection of helper functions for interacting with 'traditional',
* callback-taking functions using a promise interface.
*
* @author Renato Zannon <renato.riccieri@gmail.com>
* @author Renato Zannon
* @contributor Brian Cavalier

@@ -16,13 +14,15 @@ */

var when, promise, slice;
var when, Promise, promise, slice, _liftAll;
when = require('./when');
Promise = when.Promise;
_liftAll = require('./lib/liftAll');
promise = when.promise;
slice = [].slice;
slice = Array.prototype.slice;
return {
lift: lift,
liftAll: liftAll,
apply: apply,
call: call,
lift: lift,
bind: lift, // DEPRECATED alias for lift
promisify: promisify

@@ -62,3 +62,3 @@ };

function apply(asyncFunction, extraAsyncArgs) {
return _apply(asyncFunction, this, extraAsyncArgs);
return _apply(asyncFunction, this, extraAsyncArgs || []);
}

@@ -71,11 +71,9 @@

function _apply(asyncFunction, thisArg, extraAsyncArgs) {
return when.all(extraAsyncArgs || []).then(function(args) {
return promise(function(resolve, reject) {
var asyncArgs = args.concat(
alwaysUnary(resolve),
alwaysUnary(reject)
);
return Promise.all(extraAsyncArgs).then(function(args) {
var p = Promise._defer();
args.push(alwaysUnary(p._handler.resolve, p._handler),
alwaysUnary(p._handler.reject, p._handler));
asyncFunction.apply(thisArg, args);
asyncFunction.apply(thisArg, asyncArgs);
});
return p;
});

@@ -149,2 +147,17 @@ }

/**
* Lift all the functions/methods on src
* @param {object|function} src source whose functions will be lifted
* @param {function?} combine optional function for customizing the lifting
* process. It is passed dst, the lifted function, and the property name of
* the original function on src.
* @param {(object|function)?} dst option destination host onto which to place lifted
* functions. If not provided, liftAll returns a new object.
* @returns {*} If dst is provided, returns dst with lifted functions as
* properties. If dst not provided, returns a new object with lifted functions.
*/
function liftAll(src, combine, dst) {
return _liftAll(lift, combine, dst, src);
}
/**
* `promisify` is a version of `lift` that allows fine-grained control over the

@@ -201,27 +214,26 @@ * arguments that passed to the underlying function. It is intended to handle

var thisArg = this;
return when.all(arguments).then(function(args) {
return promise(applyPromisified);
return Promise.all(arguments).then(function(args) {
var p = Promise._defer();
function applyPromisified(resolve, reject) {
var callbackPos, errbackPos;
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);
}
if(errbackPos < callbackPos) {
insertCallback(args, errbackPos, reject);
insertCallback(args, callbackPos, resolve);
} else {
insertCallback(args, callbackPos, resolve);
insertCallback(args, errbackPos, reject);
}
asyncFunction.apply(thisArg, args);
if(errbackPos < callbackPos) {
insertCallback(args, errbackPos, p._handler.reject, p._handler);
insertCallback(args, callbackPos, p._handler.resolve, p._handler);
} else {
insertCallback(args, callbackPos, p._handler.resolve, p._handler);
insertCallback(args, errbackPos, p._handler.reject, p._handler);
}
asyncFunction.apply(thisArg, args);
return p;
});

@@ -235,5 +247,5 @@ };

function insertCallback(args, pos, callback) {
function insertCallback(args, pos, callback, thisArg) {
if(pos != null) {
callback = alwaysUnary(callback);
callback = alwaysUnary(callback, thisArg);
if(pos < 0) {

@@ -244,11 +256,10 @@ pos = args.length + pos + 2;

}
}
function alwaysUnary(fn) {
function alwaysUnary(fn, thisArg) {
return function() {
if(arguments.length <= 1) {
fn.apply(this, arguments);
fn.apply(thisArg, arguments);
} else {
fn.call(this, slice.call(arguments));
fn.call(thisArg, slice.call(arguments));
}

@@ -258,5 +269,2 @@ };

});
})(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
);
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });

@@ -5,2 +5,3 @@ /** @license MIT License (c) copyright B Cavalier & J Hann */

* cancelable.js
* @deprecated
*

@@ -20,8 +21,7 @@ * Decorator that makes a deferred "cancelable". It adds a cancel() method that

(function(define) {
define(function(require) {
define(function() {
var when = require('./when');
/**
* Makes deferred cancelable, adding a cancel() method.
* @deprecated
*

@@ -38,18 +38,14 @@ * @param deferred {Deferred} the {@link Deferred} to make cancelable

return function(deferred, canceler) {
var delegate = when.defer();
// Add a cancel method to the deferred to reject the delegate
// with the special canceled indicator.
deferred.cancel = function() {
return deferred.reject(canceler(deferred));
try {
deferred.reject(canceler(deferred));
} catch(e) {
deferred.reject(e);
}
return deferred.promise;
};
// Ensure that the original resolve, reject, and progress all forward
// to the delegate
deferred.promise.then(delegate.resolve, delegate.reject, delegate.notify);
// Replace deferred's promise with the delegate promise
deferred.promise = delegate.promise;
return deferred;

@@ -59,7 +55,4 @@ };

});
})(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
);
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(); });

@@ -0,1 +1,13 @@

### 3.0.0
* New internal architecture with significant performance improvements and memory efficiency
* New APIs
* [`when.try`](docs/api.md#whentry), [`when.lift`](docs/api.md#whenlift), [`when.reduceRight`](docs/api.md#whenreduceRight), [`when.iterate`](docs/api.md#wheniterate), [`when.unfold`](docs/api.md#whenunfold), [`when.race`](docs/api.md#whenrace)
* [`promise.with`](docs/api.md#promisewith), [`promise.else`](docs/api.md#promiseelse), [`promise.delay`](docs/api.md#promisedelay), [`promise.timeout`](docs/api.md#promisetimeout), [`promise.progress`](docs/api.md#promiseprogress)
* New liftAll variants for lifting all of an object's functions in one shot, eg. `var promisedFs = node.liftAll(require('fs'))`
* [`fn.liftAll`](docs/api.md#fnliftall), [`node.liftAll`](docs/api.md#nodeliftall), [`callbacks.liftAll`](docs/api.md#callbacksliftall)
* `when.Promise` public, inheritance-friendly, Promise constructor
* New [ES6 Promise shim](docs/es6-promise-shim.md)
* Check out the [tips for upgrading to 3.0 from 2.x](docs/api.md#upgrading-to-30-from-2x)
### 2.8.0

@@ -2,0 +14,0 @@

@@ -14,48 +14,15 @@ /** @license MIT License (c) copyright 2011-2013 original author or authors */

define(function(require) {
/*global setTimeout*/
var when, setTimer, cjsRequire, vertxSetTimer;
when = require('./when');
cjsRequire = require;
var resolve = require('./when').resolve;
try {
vertxSetTimer = cjsRequire('vertx').setTimer;
setTimer = function (f, ms) { return vertxSetTimer(ms, f); };
} catch(e) {
setTimer = setTimeout;
}
/**
* Creates a new promise that will resolve after a msec delay. If
* value is supplied, the delay will start *after* the supplied
* value is resolved.
*
* @param {number} msec delay in milliseconds
* @param {*|Promise?} value any promise or value after which
* the delay will start
* @returns {Promise} promise that is equivalent to value, only delayed
* by msec
* @deprecated Use when(value).delay(ms)
*/
return function delay(msec, value) {
// Support reversed, deprecated argument ordering
if(typeof value === 'number') {
var tmp = value;
value = msec;
msec = tmp;
}
return when.promise(function(resolve, reject, notify) {
when(value, function(val) {
setTimer(function() {
resolve(val);
}, msec);
},
reject, notify);
});
return resolve(value).delay(msec);
};
});
})(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });

@@ -1,11 +0,9 @@

/** @license MIT License (c) copyright 2013 original author or authors */
/** @license MIT License (c) copyright 2013-2014 original author or authors */
/**
* function.js
*
* Collection of helper functions for wrapping and executing 'traditional'
* synchronous functions in a promise interface.
*
* @author brian@hovercraftstudios.com
* @contributor renato.riccieri@gmail.com
* @author Brian Cavalier
* @contributor Renato Zannon
*/

@@ -16,12 +14,14 @@

var when, slice;
var when, slice, attempt, _liftAll;
when = require('./when');
slice = [].slice;
attempt = when['try'];
_liftAll = require('./lib/liftAll');
slice = Array.prototype.slice;
return {
lift: lift,
liftAll: liftAll,
call: attempt,
apply: apply,
call: call,
lift: lift,
bind: lift, // DEPRECATED alias for lift
compose: compose

@@ -34,65 +34,11 @@ };

* depends on the value returned by the function.
*
* @example
* function onlySmallNumbers(n) {
* if(n < 10) {
* return n + 10;
* } else {
* throw new Error("Calculation failed");
* }
* }
*
* // Logs '15'
* func.apply(onlySmallNumbers, [5]).then(console.log, console.error);
*
* // Logs 'Calculation failed'
* func.apply(onlySmallNumbers, [15]).then(console.log, console.error);
*
* @param {function} func function to be called
* @param {function} f function to be called
* @param {Array} [args] array of arguments to func
* @returns {Promise} promise for the return value of func
*/
function apply(func, promisedArgs) {
return _apply(func, this, promisedArgs);
function apply(f, args) {
return _apply(f, this, args || []);
}
/**
* Apply helper that allows specifying thisArg
* @private
*/
function _apply(func, thisArg, promisedArgs) {
return when.all(promisedArgs || [], function(args) {
return func.apply(thisArg, args);
});
}
/**
* Has the same behavior that {@link apply} has, with the difference that the
* arguments to the function are provided individually, while {@link apply} accepts
* a single array.
*
* @example
* function sumSmallNumbers(x, y) {
* var result = x + y;
* if(result < 10) {
* return result;
* } else {
* throw new Error("Calculation failed");
* }
* }
*
* // Logs '5'
* func.apply(sumSmallNumbers, 2, 3).then(console.log, console.error);
*
* // Logs 'Calculation failed'
* func.apply(sumSmallNumbers, 5, 10).then(console.log, console.error);
*
* @param {function} func function to be called
* @param {...*} [args] arguments that will be forwarded to the function
* @returns {Promise} promise for the return value of func
*/
function call(func /*, args... */) {
return _apply(func, this, slice.call(arguments, 1));
}
/**
* Takes a 'regular' function and returns a version of that function that

@@ -105,38 +51,10 @@ * returns a promise instead of a plain value, and handles thrown errors by

* promise arguments, and waits for their resolution.
*
* @example
* function mayThrowError(n) {
* if(n % 2 === 1) { // Normally this wouldn't be so deterministic :)
* throw new Error("I don't like odd numbers");
* } else {
* return n;
* }
* }
*
* var lifted = fn.lift(mayThrowError);
*
* // Logs "I don't like odd numbers"
* lifted(1).then(console.log, console.error);
*
* // Logs '6'
* lifted(6).then(console.log, console.error);
*
* @example
* function sumTwoNumbers(x, y) {
* return x + y;
* }
*
* var sumWithFive = fn.lifted(sumTwoNumbers, 5);
*
* // Logs '15'
* sumWithFive(10).then(console.log, console.error);
*
* @param {Function} func function to be bound
* @param {...*} [args] arguments to be prepended for the new function
* @returns {Function} a promise-returning function
* @param {Function} f function to be bound
* @param {...*} [args] arguments to be prepended for the new function
* @returns {Function} a promise-returning function
*/
function lift(func /*, args... */) {
function lift(f /*, args... */) {
var args = slice.call(arguments, 1);
return function() {
return _apply(func, this, args.concat(slice.call(arguments)));
return _apply(f, this, args.concat(slice.call(arguments)));
};

@@ -146,2 +64,27 @@ }

/**
* Apply helper that allows specifying thisArg
* @private
*/
function _apply(f, thisArg, args) {
return args.length === 0
? attempt.call(thisArg, f)
: attempt.apply(thisArg, [f].concat(args));
}
/**
* Lift all the functions/methods on src
* @param {object|function} src source whose functions will be lifted
* @param {function?} combine optional function for customizing the lifting
* process. It is passed dst, the lifted function, and the property name of
* the original function on src.
* @param {(object|function)?} dst option destination host onto which to place lifted
* functions. If not provided, liftAll returns a new object.
* @returns {*} If dst is provided, returns dst with lifted functions as
* properties. If dst not provided, returns a new object with lifted functions.
*/
function liftAll(src, combine, dst) {
return _liftAll(lift, combine, dst, src);
}
/**
* Composes multiple functions by piping their return values. It is

@@ -155,37 +98,2 @@ * transparent to whether the functions return 'regular' values or promises:

* any), are passed directly to the first function on the 'pipeline'.
*
* @example
* function getHowMuchWeWillDestroy(parameter) {
* // Makes some calculations to find out which items the modification the user
* // wants will destroy. Returns a number
* }
*
* function getUserConfirmation(itemsCount) {
* // Return a resolved promise if the user confirms the destruction,
* // and rejects it otherwise
* }
*
* function saveModifications() {
* // Makes ajax to save modifications on the server, returning a
* // promise.
* }
*
* function showNotification() {
* // Notifies that the modification was successful
* }
*
* // Composes the whole process into one function that returns a promise
* var wholeProcess = func.compose(getHowMuchWeWillDestroy,
* getUserConfirmation,
* saveModifications,
* showNotification);
*
* // Which is equivalent to
* var wholeProcess = function(parameter) {
* return fn.call(getHowMuchWeWillDestroy, parameter)
* .then(getUserConfirmation)
* .then(saveModifications)
* .then(showNotification);
* }
*
* @param {Function} f the function to which the arguments will be passed

@@ -203,3 +111,3 @@ * @param {...Function} [funcs] functions that will be composed, in order

args = slice.call(arguments);
firstPromise = _apply(f, thisArg, args);
firstPromise = attempt.apply(thisArg, [f].concat(args));

@@ -212,8 +120,4 @@ return when.reduce(funcs, function(arg, func) {

});
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
})(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
);

@@ -1,2 +0,2 @@

/** @license MIT License (c) copyright 2010-2013 original author or authors */
/** @license MIT License (c) copyright 2010-2014 original author or authors */

@@ -3,0 +3,0 @@ /**

@@ -30,9 +30,7 @@ /** @license MIT License (c) copyright 2011-2013 original author or authors */

return function() {
var self, args;
var self = this;
var args = arguments;
self = this;
args = arguments;
return when(condition(), function(exit) {
return when(f.apply(self, args)).ensure(exit);
return when(f.apply(self, args))['finally'](exit);
});

@@ -52,7 +50,5 @@ };

function n(allowed) {
var count, waiting;
var count = 0;
var waiting = [];
count = 0;
waiting = [];
return function enter() {

@@ -69,3 +65,3 @@ return when.promise(function(resolve) {

count = Math.max(count - 1, 0);
if(waiting.length) {
if(waiting.length > 0) {
waiting.shift()(exit);

@@ -72,0 +68,0 @@ }

@@ -12,34 +12,11 @@ /** @license MIT License (c) copyright 2011-2013 original author or authors */

define(function(require) {
var when, promise, keys, eachKey, owns;
when = require('./when');
promise = when.promise;
var when = require('./when');
var toPromise = when.resolve;
// Public API
keys = {
all: all,
return {
all: when.lift(all),
map: map
};
// Safe ownProp
owns = {}.hasOwnProperty;
// Use Object.keys if available, otherwise for..in
eachKey = Object.keys
? function(object, lambda) {
Object.keys(object).forEach(function(key) {
lambda(object[key], key);
});
}
: function(object, lambda) {
for(var key in object) {
if(owns.call(object, key)) {
lambda(object[key], key);
}
}
};
return keys;
/**

@@ -53,3 +30,25 @@ * Resolve all the key-value pairs in the supplied object or promise

function all(object) {
return map(object, identity);
return when.promise(function(resolve, reject, notify) {
var results = {};
var pending = 0;
for(var k in object) {
resolveOne(object[k], k);
}
if(pending === 0) {
resolve(results);
}
function resolveOne(x, k) {
++pending;
toPromise(x).then(function(x) {
results[k] = x;
if(--pending === 0) {
resolve(results);
}
}, reject, notify);
}
});
}

@@ -61,3 +60,3 @@

* will be reduced
* @param {function} mapFunc mapping function mapFunc(value) which may
* @param {function} f mapping function mapFunc(value) which may
* return either a promise or a value

@@ -67,37 +66,12 @@ * @returns {Promise} promise for an object with the mapped and fully

*/
function map(object, mapFunc) {
return when(object, function(object) {
return promise(resolveMap);
function resolveMap(resolve, reject, notify) {
var results, toResolve;
results = {};
toResolve = 0;
eachKey(object, function(value, key) {
++toResolve;
when(value, mapFunc).then(function(mapped) {
results[key] = mapped;
if(!--toResolve) {
resolve(results);
}
}, reject, notify);
});
// If there are no keys, resolve immediately
if(!toResolve) {
resolve(results);
}
}
function map(object, f) {
return toPromise(object).then(function(object) {
return all(Object.keys(object).reduce(function(o, k) {
o[k] = toPromise(object[k]).then(f);
return o;
}, {}));
});
}
function identity(x) { return x; }
});
})(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
);
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });

@@ -1,51 +0,21 @@

/** @license MIT License (c) copyright 2010-2013 original author or authors */
/** @license MIT License (c) copyright 2010-2014 original author or authors */
/** @author Brian Cavalier */
/** @author John Hann */
/**
* Licensed under the MIT License at:
* http://www.opensource.org/licenses/mit-license.php
*
* @author: Brian Cavalier
* @author: John Hann
*/
(function(define) { 'use strict';
define(function(require) {
var createAggregator, throttleReporter, simpleReporter, aggregator,
formatter, stackFilter, excludeRx, filter, reporter, logger,
rejectionMsg, reasonMsg, filteredFramesMsg, stackJumpMsg, attachPoint;
var PromiseMonitor = require('./PromiseMonitor');
var ConsoleReporter = require('./ConsoleReporter');
createAggregator = require('./aggregator');
throttleReporter = require('./throttledReporter');
simpleReporter = require('./simpleReporter');
formatter = require('./simpleFormatter');
stackFilter = require('./stackFilter');
logger = require('./logger/consoleGroup');
var traceFilter = /(node|module|timers)\.js:|when(\/(lib|monitor)\/|\.js)/i;
var promiseMonitor = new PromiseMonitor(new ConsoleReporter(traceFilter));
rejectionMsg = '=== Unhandled rejection escaped at ===';
reasonMsg = '=== Caused by reason ===';
stackJumpMsg = ' --- new call stack ---';
filteredFramesMsg = ' ...[filtered frames]...';
excludeRx = /when\.js|(module|node)\.js:\d|when\/monitor\//i;
filter = stackFilter(exclude, mergePromiseFrames);
reporter = simpleReporter(formatter(filter, rejectionMsg, reasonMsg, stackJumpMsg), logger);
aggregator = createAggregator(throttleReporter(200, reporter));
attachPoint = typeof console !== 'undefined'
? aggregator.publish(console)
: aggregator;
return aggregator;
function mergePromiseFrames(/* frames */) {
return filteredFramesMsg;
if(typeof console !== 'undefined') {
console.promiseMonitor = promiseMonitor;
}
function exclude(line) {
var rx = attachPoint.promiseStackFilter || excludeRx;
return rx.test(line);
}
return promiseMonitor;
});
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
/** @license MIT License (c) copyright 2013 original author or authors */
/**
* node/function.js
*
* Collection of helpers for interfacing with node-style asynchronous functions
* using promises.
*
* @author brian@hovercraftstudios.com
* @contributor renato.riccieri@gmail.com
* @author Brian Cavalier
*/
(function(define) {
(function(define) { 'use strict';
define(function(require) {
var when, slice, setTimer, cjsRequire, vertxSetTimer;
// DEPRECATED: Use when/node instead
return require('../node');
when = require('../when');
slice = [].slice;
cjsRequire = require;
try {
vertxSetTimer = cjsRequire('vertx').setTimer;
setTimer = function (f, ms) { return vertxSetTimer(ms, f); };
} catch(e) {
setTimer = setTimeout;
}
return {
apply: apply,
call: call,
lift: lift,
bind: lift, // DEPRECATED alias for lift
createCallback: createCallback,
bindCallback: bindCallback,
liftCallback: liftCallback
};
/**
* Takes a node-style async function and calls it immediately (with an optional
* array of arguments or promises for arguments). It returns a promise whose
* resolution depends on whether the async functions calls its callback with the
* conventional error argument or not.
*
* With this it becomes possible to leverage existing APIs while still reaping
* the benefits of promises.
*
* @example
* function onlySmallNumbers(n, callback) {
* if(n < 10) {
* callback(null, n + 10);
* } else {
* callback(new Error("Calculation failed"));
* }
* }
*
* var nodefn = require("when/node/function");
*
* // Logs '15'
* nodefn.apply(onlySmallNumbers, [5]).then(console.log, console.error);
*
* // Logs 'Calculation failed'
* nodefn.apply(onlySmallNumbers, [15]).then(console.log, console.error);
*
* @param {function} func node-style function that will be called
* @param {Array} [args] array of arguments to func
* @returns {Promise} promise for the value func passes to its callback
*/
function apply(func, args) {
return _apply(func, this, args);
}
/**
* Apply helper that allows specifying thisArg
* @private
*/
function _apply(func, thisArg, args) {
return when.all(args || []).then(function(resolvedArgs) {
var d = when.defer();
var callback = createCallback(d.resolver);
func.apply(thisArg, resolvedArgs.concat(callback));
return d.promise;
});
}
/**
* Has the same behavior that {@link apply} has, with the difference that the
* arguments to the function are provided individually, while {@link apply} accepts
* a single array.
*
* @example
* function sumSmallNumbers(x, y, callback) {
* var result = x + y;
* if(result < 10) {
* callback(null, result);
* } else {
* callback(new Error("Calculation failed"));
* }
* }
*
* // Logs '5'
* nodefn.call(sumSmallNumbers, 2, 3).then(console.log, console.error);
*
* // Logs 'Calculation failed'
* nodefn.call(sumSmallNumbers, 5, 10).then(console.log, console.error);
*
* @param {function} func node-style function that will be called
* @param {...*} [args] arguments that will be forwarded to the function
* @returns {Promise} promise for the value func passes to its callback
*/
function call(func /*, args... */) {
return _apply(func, this, slice.call(arguments, 1));
}
/**
* Takes a node-style function and returns new function that wraps the
* original and, instead of taking a callback, returns a promise. Also, it
* knows how to handle promises given as arguments, waiting for their
* resolution before executing.
*
* Upon execution, the orginal function is executed as well. If it passes
* a truthy value as the first argument to the callback, it will be
* interpreted as an error condition, and the promise will be rejected
* with it. Otherwise, the call is considered a resolution, and the promise
* is resolved with the callback's second argument.
*
* @example
* var fs = require("fs"), nodefn = require("when/node/function");
*
* var promiseRead = nodefn.lift(fs.readFile);
*
* // The promise is resolved with the contents of the file if everything
* // goes ok
* promiseRead('exists.txt').then(console.log, console.error);
*
* // And will be rejected if something doesn't work out
* // (e.g. the files does not exist)
* promiseRead('doesnt_exist.txt').then(console.log, console.error);
*
*
* @param {Function} func node-style function to be bound
* @param {...*} [args] arguments to be prepended for the new function
* @returns {Function} a promise-returning function
*/
function lift(func /*, args... */) {
var args = slice.call(arguments, 1);
return function() {
return _apply(func, this, args.concat(slice.call(arguments)));
};
}
/**
* Takes an object that responds to the resolver interface, and returns
* a function that will resolve or reject it depending on how it is called.
*
* @example
* function callbackTakingFunction(callback) {
* if(somethingWrongHappened) {
* callback(error);
* } else {
* callback(null, interestingValue);
* }
* }
*
* var when = require('when'), nodefn = require('when/node/function');
*
* var deferred = when.defer();
* callbackTakingFunction(nodefn.createCallback(deferred.resolver));
*
* deferred.promise.then(function(interestingValue) {
* // Use interestingValue
* });
*
* @param {Resolver} resolver that will be 'attached' to the callback
* @returns {Function} a node-style callback function
*/
function createCallback(resolver) {
return function(err, value) {
if(err) {
resolver.reject(err);
} else if(arguments.length > 2) {
resolver.resolve(slice.call(arguments, 1));
} else {
resolver.resolve(value);
}
};
}
/**
* Attaches a node-style callback to a promise, ensuring the callback is
* called for either fulfillment or rejection. Returns a promise with the same
* state as the passed-in promise.
*
* @example
* var deferred = when.defer();
*
* function callback(err, value) {
* // Handle err or use value
* }
*
* bindCallback(deferred.promise, callback);
*
* deferred.resolve('interesting value');
*
* @param {Promise} promise The promise to be attached to.
* @param {Function} callback The node-style callback to attach.
* @returns {Promise} A promise with the same state as the passed-in promise.
*/
function bindCallback(promise, callback) {
promise = when(promise);
if (callback) {
promise.then(success, wrapped);
}
return promise;
function success(value) {
wrapped(null, value);
}
function wrapped(err, value) {
setTimer(function () {
callback(err, value);
}, 0);
}
}
/**
* Takes a node-style callback and returns new function that accepts a
* promise, calling the original callback when the promise is either
* fulfilled or rejected with the appropriate arguments.
*
* @example
* var deferred = when.defer();
*
* function callback(err, value) {
* // Handle err or use value
* }
*
* var wrapped = liftCallback(callback);
*
* // `wrapped` can now be passed around at will
* wrapped(deferred.promise);
*
* deferred.resolve('interesting value');
*
* @param {Function} callback The node-style callback to wrap.
* @returns {Function} The lifted, promise-accepting function.
*/
function liftCallback(callback) {
return function(promise) {
return bindCallback(promise, callback);
};
}
});
})(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
);
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
{
"name": "when",
"version": "2.8.0",
"version": "3.0.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", "ender"],
"keywords": [
"cujo",
"Promises/A+",
"promises-aplus",
"promise",
"promises",
"deferred",
"deferreds",
"when",
"async",
"asynchronous",
"ender"
],
"homepage": "http://cujojs.com",

@@ -42,3 +54,4 @@ "licenses": [

"devDependencies": {
"curl": "https://github.com/cujojs/curl/tarball/0.7.3",
"curl": "git://github.com/cujojs/curl",
"poly": "git://github.com/cujojs/poly",
"test-support": "~0.3",

@@ -51,3 +64,3 @@ "promises-aplus-tests": "~2",

"main": "when",
"ender": { "files": ["*.js", "node/*.js", "unfold/*.js", "monitor/*.js"] },
"ender": { "files": ["*.js", "lib/*.js", "node/*.js", "unfold/*.js", "monitor/*.js"] },
"directories": {

@@ -58,9 +71,10 @@ "test": "test"

"test": "jshint . && buster test -e node -r specification && promises-aplus-tests test/promises-aplus-adapter.js --reporter spec",
"ci": "npm test && sauceme",
"ci": "npm test && sauceme -b test/browsers.json",
"tunnel": "sauceme -m",
"start": "buster static -e browser",
"benchmark": "node benchmark/promise && node benchmark/map",
"browserify": "browserify -s when build/when.browserify.js -o build/when.js",
"browserify-debug": "browserify -s when build/when.browserify-debug.js -o build/when.js"
"browserify-es6": "browserify -s Promise es6-shim/Promise.browserify-es6.js --no-detect-globals -o es6-shim/Promise.js",
"browserify": "browserify -s when build/when.browserify.js --no-detect-globals -o build/when.js",
"browserify-debug": "browserify -s when build/when.browserify-debug.js --no-detect-globals -o build/when.js"
}
}

@@ -16,7 +16,6 @@ /** @license MIT License (c) copyright 2011-2013 original author or authors */

var when, slice;
var when = require('./when');
var all = when.Promise.all;
var slice = Array.prototype.slice;
when = require('./when');
slice = Array.prototype.slice;
/**

@@ -31,5 +30,5 @@ * Run array of tasks in parallel

return function parallel(tasks /*, args... */) {
return when.all(slice.call(arguments, 1)).then(function(args) {
return all(slice.call(arguments, 1)).then(function(args) {
return when.map(tasks, function(task) {
return task.apply(null, args);
return task.apply(void 0, args);
});

@@ -40,7 +39,4 @@ });

});
})(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
);
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });

@@ -17,7 +17,6 @@ /** @license MIT License (c) copyright 2011-2013 original author or authors */

var when, slice;
var when = require('./when');
var all = when.Promise.all;
var slice = Array.prototype.slice;
when = require('./when');
slice = Array.prototype.slice;
/**

@@ -42,3 +41,3 @@ * Run array of tasks in a pipeline where the next

return when.all(slice.call(arguments, 1)).then(function(args) {
return all(slice.call(arguments, 1)).then(function(args) {
return when.reduce(tasks, function(arg, task) {

@@ -51,7 +50,4 @@ return runTask(arg, task);

});
})(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
);
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });

@@ -11,12 +11,10 @@ /** @license MIT License (c) copyright 2012-2013 original author or authors */

(function (define) {
'use strict';
(function (define) { 'use strict';
define(function(require) {
var when, cancelable, delay, fn, undef;
var when, attempt, cancelable;
when = require('./when');
attempt = when['try'];
cancelable = require('./cancelable');
delay = require('./delay');
fn = require('./function');

@@ -74,3 +72,3 @@ /**

interval = (function (interval) {
return function () { return delay(interval); };
return function () { return when().delay(interval); };
})(interval);

@@ -84,4 +82,4 @@ }

function schedule(result) {
fn.apply(interval).then(vote, reject);
if (result !== undef) {
attempt(interval).then(vote, reject);
if (result !== void 0) {
deferred.notify(result);

@@ -108,4 +106,3 @@ }

schedule();
}
else {
} else {
// if work() is blocking, vote will also block

@@ -116,3 +113,3 @@ vote();

// make the promise cancelable
deferred.promise = beget(deferred.promise);
deferred.promise = Object.create(deferred.promise);
deferred.promise.cancel = deferred.cancel;

@@ -123,15 +120,3 @@

function F() {}
function beget(p) {
F.prototype = p;
var newPromise = new F();
F.prototype = null;
return newPromise;
}
});
})(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
);
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });

@@ -5,17 +5,18 @@ <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
when.js
=======
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 a rock solid, battle-tested [Promises/A+](http://promises-aplus.github.com/promises-spec) and `when()` implementation, including a complete [ES6 Promise shim](docs/es6-promise-shim.md). It's a powerful combination of small size, high performance, and rich features:
* A rock solid, battle-tested Promise implementation
* Resolving, settling, mapping, and reducing arrays of promises
* Executing tasks in parallel and sequence
* Transforming Node-style and other callback-based APIs into promise-based APIs
* Resolve arrays and hashes of promises, as well as infinite promise sequences
* Execute tasks in parallel or sequentially
* Transform Node-style and other callback-based APIs into promise-based APIs
It passes the [Promises/A+ Test Suite](https://github.com/promises-aplus/promises-tests), is [very fast](https://github.com/cujojs/promise-perf-tests#test-results) and compact, and has no external dependencies.
When.js is one of the many stand-alone components of [cujoJS](http://cujojs.com), the JavaScript Architectural Toolkit.
Check it out:
- [What's new](CHANGES.md)
- [API docs](docs/api.md#api)
- [Examples](https://github.com/cujojs/when/wiki/Examples)
- [More info on the wiki](https://github.com/cujojs/when/wiki)
- Read more about how [promises simplify async programming](http://know.cujojs.com/tutorials/async/simplifying-async-with-promises)

@@ -27,8 +28,12 @@ Installation

Availble as `when` through [bower](http://bower.io) and [yeoman](https://github.com/yeoman/yo), or just clone the repo and load `when.js` from the root. When.js is AMD-compatible out of the box, so no need for shims.
Availble as `when` through [bower](http://bower.io), or just clone the repo and load `when.js` from the root.
```
bower install --save when
```
#### CommonJS/Node
```
npm install when
npm install --save when
```

@@ -89,9 +94,6 @@

- For more examples, see [examples &raquo;](https://github.com/cujojs/when/wiki/Examples)
- For the full documentation see [api docs &raquo;](docs/api.md#api)
License
-------
Licensed under MIT. [See the license here &raquo;](LICENSE.txt)
Licensed under MIT. [Full license here &raquo;](LICENSE.txt)

@@ -98,0 +100,0 @@ Contributing

@@ -16,7 +16,6 @@ /** @license MIT License (c) copyright 2011-2013 original author or authors */

var when, slice;
var when = require('./when');
var all = when.Promise.all;
var slice = Array.prototype.slice;
when = require('./when');
slice = Array.prototype.slice;
/**

@@ -33,5 +32,5 @@ * Run array of tasks in sequence with no overlap

return when.all(slice.call(arguments, 1)).then(function(args) {
return all(slice.call(arguments, 1)).then(function(args) {
return when.reduce(tasks, function(results, task) {
return when(task.apply(null, args), addResult);
return when(task.apply(void 0, args), addResult);
}, results);

@@ -47,7 +46,4 @@ });

});
})(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
);
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });

@@ -15,58 +15,14 @@ /** @license MIT License (c) copyright 2011-2013 original author or authors */

define(function(require) {
/*global setTimeout,clearTimeout*/
var when, setTimer, cancelTimer, cjsRequire, vertx;
when = require('./when');
cjsRequire = require;
var resolve = require('./when').resolve;
try {
vertx = cjsRequire('vertx');
setTimer = function (f, ms) { return vertx.setTimer(ms, f); };
cancelTimer = vertx.cancelTimer;
} catch (e) {
setTimer = setTimeout;
cancelTimer = clearTimeout;
}
/**
* Returns a new promise that will automatically reject after msec if
* the supplied trigger doesn't resolve or reject before that.
*
* @param {number} msec timeout in milliseconds
* @param {*|Promise} trigger any promise or value that should trigger the
* returned promise to resolve or reject before the msec timeout
* @returns {Promise} promise that will timeout after msec, or be
* equivalent to trigger if resolved/rejected before msec
* @deprecated Use when(trigger).timeout(ms)
*/
return function timeout(msec, trigger) {
// Support reversed, deprecated argument ordering
if(typeof trigger === 'number') {
var tmp = trigger;
trigger = msec;
msec = tmp;
}
return when.promise(function(resolve, reject, notify) {
var timeoutRef = setTimer(function onTimeout() {
reject(new Error('timed out after ' + msec + 'ms'));
}, msec);
when(trigger,
function onFulfill(value) {
cancelTimer(timeoutRef);
resolve(value);
},
function onReject(reason) {
cancelTimer(timeoutRef);
reject(reason);
},
notify
);
});
return resolve(trigger).timeout(msec);
};
});
})(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });

@@ -10,33 +10,9 @@ /** @license MIT License (c) copyright B Cavalier & J Hann */

var when = require('./when');
/**
* Anamorphic unfold/map that generates values by applying
* handler(generator(seed)) iteratively until condition(seed)
* returns true.
* @param {function} unspool function that generates a [value, newSeed]
* given a seed.
* @param {function} condition function that, given the current seed, returns
* truthy when the unfold should stop
* @param {function} handler function to handle the value produced by generator
* @param seed {*|Promise} any value or promise
* @return {Promise} the result of the unfold
* @deprecated Use when.unfold
*/
return function unfold(unspool, condition, handler, seed) {
return when(seed, function(seed) {
return require('./when').unfold;
return when(condition(seed), function(done) {
return done ? seed : when.resolve(unspool(seed)).spread(next);
});
function next(item, newSeed) {
return when(handler(item), function() {
return unfold(unspool, condition, handler, newSeed);
});
}
});
};
});
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); } );
/** @license MIT License (c) copyright B Cavalier & J Hann */
/**
* unfold
* @author: brian@hovercraftstudios.com
*/
(function(define) {
define(function(require) {
var when, unfold;
var unfold = require('../when').unfold;
when = require('../when');
unfold = require('../unfold');
/**
* @deprecated
* Given a seed and generator, produces an Array. Effectively the

@@ -37,6 +31,3 @@ * dual (opposite) of when.reduce()

});
})(
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }
// Boilerplate for AMD and Node
);
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });

@@ -1,13 +0,9 @@

/** @license MIT License (c) copyright 2011-2013 original author or authors */
/** @license MIT License (c) copyright 2010-2014 original author or authors */
/**
* A lightweight CommonJS Promises/A and when() implementation
* when is part of the cujo.js family of libraries (http://cujojs.com/)
*
* Licensed under the MIT License at:
* http://www.opensource.org/licenses/mit-license.php
*
* when is part of the cujoJS family of libraries (http://cujojs.com/)
* @author Brian Cavalier
* @author John Hann
* @version 2.8.0
* @version 3.0.0
*/

@@ -17,41 +13,68 @@ (function(define) { 'use strict';

var timer = require('./lib/timer');
var timed = require('./lib/timed');
var array = require('./lib/array');
var flow = require('./lib/flow');
var inspect = require('./lib/inspect');
var generate = require('./lib/iterate');
var progress = require('./lib/progress');
var withThis = require('./lib/with');
var Promise = require('./lib/Promise');
Promise = [array, flow, generate, progress, inspect, withThis]
.reduceRight(function(Promise, feature) {
return feature(Promise);
}, timed(timer.set, timer.clear, Promise));
var resolve = Promise.resolve;
var slice = Array.prototype.slice;
// Public API
when.promise = promise; // Create a pending promise
when.resolve = resolve; // Create a resolved promise
when.reject = reject; // Create a rejected promise
when.defer = defer; // Create a {promise, resolver} pair
when.promise = promise; // Create a pending promise
when.resolve = Promise.resolve; // Create a resolved promise
when.reject = Promise.reject; // Create a rejected promise
when.join = join; // Join 2 or more promises
when.lift = lift; // lift a function to return promises
when['try'] = tryCall; // call a function and return a promise
when.attempt = tryCall; // alias for when.try
when.all = all; // Resolve a list of promises
when.map = map; // Array.map() for promises
when.reduce = reduce; // Array.reduce() for promises
when.settle = settle; // Settle a list of promises
when.iterate = Promise.iterate; // Generate a stream of promises
when.unfold = Promise.unfold; // Generate a stream of promises
when.any = any; // One-winner race
when.some = some; // Multi-winner race
when.join = join; // Join 2 or more promises
when.isPromise = isPromiseLike; // DEPRECATED: use isPromiseLike
when.isPromiseLike = isPromiseLike; // Is something promise-like, aka thenable
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.map = map; // Array.map() for promises
when.reduce = reduce; // Array.reduce() for promises
when.reduceRight = 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
/**
* Register an observer for a promise or immediate value.
* When x, which may be a promise, thenable, or non-promise value,
*
* @param {*} promiseOrValue
* @param {function?} [onFulfilled] callback to be called when promiseOrValue is
* @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 promiseOrValue is
* @param {function?} onRejected callback to be called when x is
* rejected.
* @param {function?} [onProgress] callback to be called when progress updates
* are issued for promiseOrValue.
* @returns {Promise} a new {@link Promise} that will complete with the return
* @param {function?} onProgress callback to be called when progress updates
* are issued for x.
* @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(promiseOrValue, onFulfilled, onRejected, onProgress) {
// Get a trusted promise for the input promiseOrValue, and then
// register promise handlers
return cast(promiseOrValue).then(onFulfilled, onRejected, onProgress);
function when(x, onFulfilled, onRejected, onProgress) {
var p = resolve(x);
return arguments.length < 2 ? p : p.then(onFulfilled, onRejected, onProgress);
}

@@ -65,225 +88,35 @@

function promise(resolver) {
return new Promise(resolver,
monitorApi.PromiseStatus && monitorApi.PromiseStatus());
return new Promise(resolver);
}
/**
* Trusted Promise constructor. A Promise created from this constructor is
* a trusted when.js promise. Any other duck-typed promise is considered
* untrusted.
* @constructor
* @returns {Promise} promise whose fate is determine by resolver
* @name Promise
* 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 Promise(resolver, status) {
var self, value, consumers = [];
self = this;
this._status = status;
this.inspect = inspect;
this._when = _when;
// Call the provider resolver to seal the promise's fate
try {
resolver(promiseResolve, promiseReject, promiseNotify);
} catch(e) {
promiseReject(e);
}
/**
* Returns a snapshot of this promise's current status at the instant of call
* @returns {{state:String}}
*/
function inspect() {
return value ? value.inspect() : toPendingState();
}
/**
* Private message delivery. Queues and delivers messages to
* the promise's ultimate fulfillment value or rejection reason.
* @private
*/
function _when(resolve, notify, onFulfilled, onRejected, onProgress) {
consumers ? consumers.push(deliver) : enqueue(function() { deliver(value); });
function deliver(p) {
p._when(resolve, notify, onFulfilled, onRejected, onProgress);
}
}
/**
* Transition from pre-resolution state to post-resolution state, notifying
* all listeners of the ultimate fulfillment or rejection
* @param {*} val resolution value
*/
function promiseResolve(val) {
if(!consumers) {
return;
}
var queue = consumers;
consumers = undef;
value = coerce(self, val);
enqueue(function () {
if(status) {
updateStatus(value, status);
}
runHandlers(queue, value);
});
}
/**
* Reject this promise with the supplied reason, which will be used verbatim.
* @param {*} reason reason for the rejection
*/
function promiseReject(reason) {
promiseResolve(new RejectedPromise(reason));
}
/**
* Issue a progress event, notifying all progress listeners
* @param {*} update progress event payload to pass to all listeners
*/
function promiseNotify(update) {
if(consumers) {
var queue = consumers;
enqueue(function () {
runHandlers(queue, new ProgressingPromise(update));
});
}
}
function lift(f) {
return function() {
return _apply(f, this, slice.call(arguments));
};
}
promisePrototype = Promise.prototype;
/**
* Register handlers for this promise.
* @param [onFulfilled] {Function} fulfillment handler
* @param [onRejected] {Function} rejection handler
* @param [onProgress] {Function} progress handler
* @return {Promise} new Promise
*/
promisePrototype.then = function(onFulfilled, onRejected, onProgress) {
var self = this;
return new Promise(function(resolve, reject, notify) {
self._when(resolve, notify, onFulfilled, onRejected, onProgress);
}, this._status && this._status.observed());
};
/**
* Register a rejection handler. Shortcut for .then(undefined, onRejected)
* @param {function?} onRejected
* @return {Promise}
*/
promisePrototype['catch'] = promisePrototype.otherwise = function(onRejected) {
return this.then(undef, onRejected);
};
/**
* Ensures that onFulfilledOrRejected will be called regardless of whether
* this promise is fulfilled or rejected. onFulfilledOrRejected WILL NOT
* receive the promises' value or reason. Any returned value will be disregarded.
* onFulfilledOrRejected may throw or return a rejected promise to signal
* an additional error.
* @param {function} onFulfilledOrRejected handler to be called regardless of
* fulfillment or rejection
* Call f in a future turn, with the supplied args, and return a promise
* for the result.
* @param {function} f
* @returns {Promise}
*/
promisePrototype['finally'] = promisePrototype.ensure = function(onFulfilledOrRejected) {
return typeof onFulfilledOrRejected === 'function'
? this.then(injectHandler, injectHandler)['yield'](this)
: this;
function injectHandler() {
return resolve(onFulfilledOrRejected());
}
};
/**
* Terminate a promise chain by handling the ultimate fulfillment value or
* rejection reason, and assuming responsibility for all errors. if an
* error propagates out of handleResult or handleFatalError, it will be
* rethrown to the host, resulting in a loud stack track on most platforms
* and a crash on some.
* @param {function?} handleResult
* @param {function?} handleError
* @returns {undefined}
*/
promisePrototype.done = function(handleResult, handleError) {
this.then(handleResult, handleError)['catch'](crash);
};
/**
* Shortcut for .then(function() { return value; })
* @param {*} value
* @return {Promise} a promise that:
* - is fulfilled if value is not a promise, or
* - if value is a promise, will fulfill with its value, or reject
* with its reason.
*/
promisePrototype['yield'] = function(value) {
return this.then(function() {
return value;
});
};
/**
* Runs a side effect when this promise fulfills, without changing the
* fulfillment value.
* @param {function} onFulfilledSideEffect
* @returns {Promise}
*/
promisePrototype.tap = function(onFulfilledSideEffect) {
return this.then(onFulfilledSideEffect)['yield'](this);
};
/**
* Assumes that this promise will fulfill with an array, and arranges
* for the onFulfilled to be called with the array as its argument list
* i.e. onFulfilled.apply(undefined, array).
* @param {function} onFulfilled function to receive spread arguments
* @return {Promise}
*/
promisePrototype.spread = function(onFulfilled) {
return this.then(function(array) {
// array may contain promises, so resolve its contents.
return all(array, function(array) {
return onFulfilled.apply(undef, array);
});
});
};
/**
* Shortcut for .then(onFulfilledOrRejected, onFulfilledOrRejected)
* @deprecated
*/
promisePrototype.always = function(onFulfilledOrRejected, onProgress) {
return this.then(onFulfilledOrRejected, onFulfilledOrRejected, onProgress);
};
/**
* Casts x to a trusted promise. If x is already a trusted promise, it is
* returned, otherwise a new trusted Promise which follows x is returned.
* @param {*} x
* @returns {Promise}
*/
function cast(x) {
return x instanceof Promise ? x : resolve(x);
function tryCall(f /*, args... */) {
/*jshint validthis:true */
return _apply(f, this, slice.call(arguments, 1));
}
/**
* Returns a resolved promise. The returned promise will be
* - fulfilled with promiseOrValue if it is a value, or
* - if promiseOrValue is a promise
* - fulfilled with promiseOrValue's value after it is fulfilled
* - rejected with promiseOrValue's reason after it is rejected
* In contract to cast(x), this always creates a new Promise
* @param {*} x
* @return {Promise}
* try/lift helper that allows specifying thisArg
* @private
*/
function resolve(x) {
return promise(function(resolve) {
resolve(x);
function _apply(func, thisArg, args) {
return Promise.all(args).then(function(args) {
return func.apply(thisArg, args);
});

@@ -293,223 +126,25 @@ }

/**
* Returns a rejected promise for the supplied promiseOrValue. The returned
* promise will be rejected with:
* - promiseOrValue, if it is a value, or
* - if promiseOrValue is a promise
* - promiseOrValue's value after it is fulfilled
* - promiseOrValue's reason after it is rejected
* @deprecated The behavior of when.reject in 3.0 will be to reject
* with x VERBATIM
* @param {*} x the rejected value of the returned promise
* @return {Promise} rejected promise
*/
function reject(x) {
return when(x, function(e) {
return new RejectedPromise(e);
});
}
/**
* Creates a {promise, resolver} pair, either or both of which
* may be given out safely to consumers.
* The resolver has resolve, reject, and progress. The promise
* has then plus extended promise API.
*
* @return {{
* promise: Promise,
* resolve: function:Promise,
* reject: function:Promise,
* notify: function:Promise
* resolver: {
* resolve: function:Promise,
* reject: function:Promise,
* notify: function:Promise
* }}}
* @return {{promise: Promise, resolve: function, reject: function, notify: function}}
*/
function defer() {
var deferred, pending, resolved;
// Optimize object shape
deferred = {
promise: undef, resolve: undef, reject: undef, notify: undef,
resolver: { resolve: undef, reject: undef, notify: undef }
};
deferred.promise = pending = promise(makeDeferred);
return deferred;
function makeDeferred(resolvePending, rejectPending, notifyPending) {
deferred.resolve = deferred.resolver.resolve = function(value) {
if(resolved) {
return resolve(value);
}
resolved = true;
resolvePending(value);
return pending;
};
deferred.reject = deferred.resolver.reject = function(reason) {
if(resolved) {
return resolve(new RejectedPromise(reason));
}
resolved = true;
rejectPending(reason);
return pending;
};
deferred.notify = deferred.resolver.notify = function(update) {
notifyPending(update);
return update;
};
}
return new Deferred();
}
/**
* Run a queue of functions as quickly as possible, passing
* value to each.
*/
function runHandlers(queue, value) {
for (var i = 0; i < queue.length; i++) {
queue[i](value);
}
}
function Deferred() {
var p = Promise._defer();
/**
* Coerces x to a trusted Promise
* @param {*} x thing to coerce
* @returns {*} Guaranteed to return a trusted Promise. If x
* is trusted, returns x, otherwise, returns a new, trusted, already-resolved
* Promise whose resolution value is:
* * the resolution value of x if it's a foreign promise, or
* * x if it's a value
*/
function coerce(self, x) {
if (x === self) {
return new RejectedPromise(new TypeError());
}
function resolve(x) { p._handler.resolve(x); }
function reject(x) { p._handler.reject(x); }
function notify(x) { p._handler.notify(x); }
if (x instanceof Promise) {
return x;
}
try {
var untrustedThen = x === Object(x) && x.then;
return typeof untrustedThen === 'function'
? assimilate(untrustedThen, x)
: new FulfilledPromise(x);
} catch(e) {
return new RejectedPromise(e);
}
this.promise = p;
this.resolve = resolve;
this.reject = reject;
this.notify = notify;
this.resolver = { resolve: resolve, reject: reject, notify: notify };
}
/**
* Safely assimilates a foreign thenable by wrapping it in a trusted promise
* @param {function} untrustedThen x's then() method
* @param {object|function} x thenable
* @returns {Promise}
*/
function assimilate(untrustedThen, x) {
return promise(function (resolve, reject) {
enqueue(function() {
try {
fcall(untrustedThen, x, resolve, reject);
} catch(e) {
reject(e);
}
});
});
}
makePromisePrototype = Object.create ||
function(o) {
function PromisePrototype() {}
PromisePrototype.prototype = o;
return new PromisePrototype();
};
/**
* Creates a fulfilled, local promise as a proxy for a value
* NOTE: must never be exposed
* @private
* @param {*} value fulfillment value
* @returns {Promise}
*/
function FulfilledPromise(value) {
this.value = value;
}
FulfilledPromise.prototype = makePromisePrototype(promisePrototype);
FulfilledPromise.prototype.inspect = function() {
return toFulfilledState(this.value);
};
FulfilledPromise.prototype._when = function(resolve, _, onFulfilled) {
try {
resolve(typeof onFulfilled === 'function' ? onFulfilled(this.value) : this.value);
} catch(e) {
resolve(new RejectedPromise(e));
}
};
/**
* Creates a rejected, local promise as a proxy for a value
* NOTE: must never be exposed
* @private
* @param {*} reason rejection reason
* @returns {Promise}
*/
function RejectedPromise(reason) {
this.value = reason;
}
RejectedPromise.prototype = makePromisePrototype(promisePrototype);
RejectedPromise.prototype.inspect = function() {
return toRejectedState(this.value);
};
RejectedPromise.prototype._when = function(resolve, _, __, onRejected) {
try {
resolve(typeof onRejected === 'function' ? onRejected(this.value) : this);
} catch(e) {
resolve(new RejectedPromise(e));
}
};
/**
* Create a progress promise with the supplied update.
* @private
* @param {*} value progress update value
* @return {Promise} progress promise
*/
function ProgressingPromise(value) {
this.value = value;
}
ProgressingPromise.prototype = makePromisePrototype(promisePrototype);
ProgressingPromise.prototype._when = function(_, notify, f, r, u) {
try {
notify(typeof u === 'function' ? u(this.value) : this.value);
} catch(e) {
notify(e);
}
};
/**
* Update a PromiseStatus monitor object with the outcome
* of the supplied value promise.
* @param {Promise} value
* @param {PromiseStatus} status
*/
function updateStatus(value, status) {
value.then(statusFulfilled, statusRejected);
function statusFulfilled() { status.fulfilled(); }
function statusRejected(r) { status.rejected(r); }
}
/**
* Determines if x is promise-like, i.e. a thenable object

@@ -527,133 +162,31 @@ * NOTE: Will return true for *any thenable object*, and isn't truly

/**
* Initiates a competitive race, returning a promise that will resolve when
* howMany of the supplied promisesOrValues have resolved, or will reject when
* it becomes impossible for howMany to resolve, for example, when
* (promisesOrValues.length - howMany) + 1 input promises reject.
*
* @param {Array} promisesOrValues array of anything, may contain a mix
* of promises and values
* @param howMany {number} number of promisesOrValues to resolve
* @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
* resolved first, or will reject with an array of
* (promisesOrValues.length - howMany) + 1 rejection reasons.
*/
function some(promisesOrValues, howMany, onFulfilled, onRejected, onProgress) {
return when(promisesOrValues, function(promisesOrValues) {
return promise(resolveSome).then(onFulfilled, onRejected, onProgress);
function resolveSome(resolve, reject, notify) {
var toResolve, toReject, values, reasons, fulfillOne, rejectOne, len, i;
len = promisesOrValues.length >>> 0;
toResolve = Math.max(0, Math.min(howMany, len));
values = [];
toReject = (len - toResolve) + 1;
reasons = [];
// No items in the input, resolve immediately
if (!toResolve) {
resolve(values);
} else {
rejectOne = function(reason) {
reasons.push(reason);
if(!--toReject) {
fulfillOne = rejectOne = identity;
reject(reasons);
}
};
fulfillOne = function(val) {
// This orders the values based on promise resolution order
values.push(val);
if (!--toResolve) {
fulfillOne = rejectOne = identity;
resolve(values);
}
};
for(i = 0; i < len; ++i) {
if(i in promisesOrValues) {
when(promisesOrValues[i], fulfiller, rejecter, notify);
}
}
}
function rejecter(reason) {
rejectOne(reason);
}
function fulfiller(val) {
fulfillOne(val);
}
}
});
}
/**
* Initiates a competitive race, returning a promise that will resolve when
* any one of the supplied promisesOrValues has resolved or will reject when
* *all* promisesOrValues have rejected.
*
* @param {Array|Promise} promisesOrValues array of anything, may contain a mix
* of {@link Promise}s and values
* @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
* will reject with an array of all rejected inputs.
*/
function any(promisesOrValues, onFulfilled, onRejected, onProgress) {
function unwrapSingleResult(val) {
return onFulfilled ? onFulfilled(val[0]) : val[0];
}
return some(promisesOrValues, 1, unwrapSingleResult, onRejected, onProgress);
}
/**
* Return a promise that will resolve only once all the supplied promisesOrValues
* 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 promisesOrValues.
* @memberOf when
*
* @param {Array|Promise} promisesOrValues array of anything, may contain a mix
* of {@link Promise}s and values
* @param {function?} [onFulfilled] DEPRECATED, use returnedPromise.then()
* @param {function?} [onRejected] DEPRECATED, use returnedPromise.then()
* @param {function?} [onProgress] DEPRECATED, use returnedPromise.then()
* containing the resolution values of each of the arguments.
* @param {...*} arguments may be a mix of promises and values
* @returns {Promise}
*/
function all(promisesOrValues, onFulfilled, onRejected, onProgress) {
return _map(promisesOrValues, identity).then(onFulfilled, onRejected, onProgress);
function join(/* ...promises */) {
return Promise.all(arguments);
}
/**
* Joins multiple promises into a single returned promise.
* @return {Promise} a promise that will fulfill when *all* the input promises
* have fulfilled, or will reject when *any one* of the input promises rejects.
* 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 join(/* ...promises */) {
return _map(arguments, identity);
function all(promises) {
return when(promises, Promise.all);
}
/**
* 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.
* 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}
*/
function settle(array) {
return _map(array, toFulfilledState, toRejectedState);
function settle(promises) {
return when(promises, Promise.settle);
}

@@ -664,3 +197,3 @@

* but input array may contain promises or values.
* @param {Array|Promise} array array of anything, may contain promises and values
* @param {Array|Promise} promises array of anything, may contain promises and values
* @param {function} mapFunc map function which may return a promise or value

@@ -670,51 +203,5 @@ * @returns {Promise} promise that will fulfill with an array of mapped values

*/
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) {
return new Promise(resolveMap);
function resolveMap(resolve, reject, notify) {
var results, len, toResolve, i;
// Since we know the resulting length, we can preallocate the results
// array to avoid array expansions.
toResolve = len = array.length >>> 0;
results = [];
if(!toResolve) {
resolve(results);
return;
}
// 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;
}
}
function resolveOne(item, i) {
when(item, mapFunc, fallback).then(function(mapped) {
results[i] = mapped;
if(!--toResolve) {
resolve(results);
}
}, reject, notify);
}
}
function map(promises, mapFunc) {
return when(promises, function(promises) {
return Promise.map(promises, mapFunc);
});

@@ -729,215 +216,38 @@ }

*
* @param {Array|Promise} promise array or promise for an array of anything,
* @param {Array|Promise} promises array or promise for an array of anything,
* may contain a mix of promises and values.
* @param {function} reduceFunc reduce function reduce(currentValue, nextValue, index, total),
* where total is the total number of items being reduced, and will be the same
* in each call to reduceFunc.
* @param {function} f reduce function reduce(currentValue, nextValue, index)
* @returns {Promise} that will resolve to the final reduced value
*/
function reduce(promise, reduceFunc /*, initialValue */) {
var args = fcall(slice, arguments, 1);
return when(promise, function(array) {
var total;
total = array.length;
// Wrap the supplied reduceFunc with one that handles promises and then
// delegates to the supplied.
args[0] = function (current, val, i) {
return when(current, function (c) {
return when(val, function (value) {
return reduceFunc(c, value, i, total);
});
});
};
return reduceArray.apply(array, args);
function reduce(promises, f /*, initialValue */) {
/*jshint unused:false*/
var args = slice.call(arguments, 1);
return when(promises, function(array) {
args.unshift(array);
return Promise.reduce.apply(Promise, args);
});
}
// Snapshot states
/**
* Creates a fulfilled state snapshot
* @private
* @param {*} x any value
* @returns {{state:'fulfilled',value:*}}
* Traditional reduce function, similar to `Array.prototype.reduceRight()`, but
* input may contain promises and/or values, and reduceFunc
* may return either a value or a promise, *and* initialValue may
* be a promise for the starting value.
*
* @param {Array|Promise} promises array or promise for an array of anything,
* may contain a mix of promises and values.
* @param {function} f reduce function reduce(currentValue, nextValue, index)
* @returns {Promise} that will resolve to the final reduced value
*/
function toFulfilledState(x) {
return { state: 'fulfilled', value: x };
function reduceRight(promises, f /*, initialValue */) {
/*jshint unused:false*/
var args = slice.call(arguments, 1);
return when(promises, function(array) {
args.unshift(array);
return Promise.reduceRight.apply(Promise, args);
});
}
/**
* 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' };
}
//
// Internals, utilities, etc.
//
var promisePrototype, makePromisePrototype, reduceArray, slice, fcall, nextTick, handlerQueue,
funcProto, call, arrayProto, monitorApi,
capturedSetTimeout, cjsRequire, MutationObs, undef;
cjsRequire = require;
//
// Shared handler queue processing
//
// Credit to Twisol (https://github.com/Twisol) for suggesting
// this type of extensible queue + trampoline approach for
// next-tick conflation.
handlerQueue = [];
/**
* Enqueue a task. If the queue is not currently scheduled to be
* drained, schedule it.
* @param {function} task
*/
function enqueue(task) {
if(handlerQueue.push(task) === 1) {
nextTick(drainQueue);
}
}
/**
* 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.
*/
function drainQueue() {
runHandlers(handlerQueue);
handlerQueue = [];
}
// Allow attaching the monitor to when() if env has no console
monitorApi = typeof console !== 'undefined' ? console : when;
// Sniff "best" async scheduling option
// Prefer process.nextTick or MutationObserver, then check for
// vertx and finally fall back to setTimeout
/*global process,document,setTimeout,MutationObserver,WebKitMutationObserver*/
if (typeof process === 'object' && process.nextTick) {
nextTick = process.nextTick;
} else if(MutationObs =
(typeof MutationObserver === 'function' && MutationObserver) ||
(typeof WebKitMutationObserver === 'function' && WebKitMutationObserver)) {
nextTick = (function(document, MutationObserver, drainQueue) {
var el = document.createElement('div');
new MutationObserver(drainQueue).observe(el, { attributes: true });
return function() {
el.setAttribute('x', 'x');
};
}(document, MutationObs, drainQueue));
} else {
try {
// vert.x 1.x || 2.x
nextTick = cjsRequire('vertx').runOnLoop || cjsRequire('vertx').runOnContext;
} catch(ignore) {
// capture setTimeout to avoid being caught by fake timers
// used in time based tests
capturedSetTimeout = setTimeout;
nextTick = function(t) { capturedSetTimeout(t, 0); };
}
}
//
// Capture/polyfill function and array utils
//
// Safe function calls
funcProto = Function.prototype;
call = funcProto.call;
fcall = funcProto.bind
? call.bind(call)
: function(f, context) {
return f.apply(context, slice.call(arguments, 2));
};
// Safe array ops
arrayProto = [];
slice = arrayProto.slice;
// ES5 reduce implementation if native not available
// See: http://es5.github.com/#x15.4.4.21 as there are many
// specifics and edge cases. ES5 dictates that reduce.length === 1
// This implementation deviates from ES5 spec in the following ways:
// 1. It does not check if reduceFunc is a Callable
reduceArray = arrayProto.reduce ||
function(reduceFunc /*, initialValue */) {
/*jshint maxcomplexity: 7*/
var arr, args, reduced, len, i;
i = 0;
arr = Object(this);
len = arr.length >>> 0;
args = arguments;
// If no initialValue, use first item of array (we know length !== 0 here)
// and adjust i to start at second item
if(args.length <= 1) {
// Skip to the first real element in the array
for(;;) {
if(i in arr) {
reduced = arr[i++];
break;
}
// If we reached the end of the array without finding any real
// elements, it's a TypeError
if(++i >= len) {
throw new TypeError();
}
}
} else {
// If initialValue provided, use it
reduced = args[1];
}
// Do the actual reduce
for(;i < len; ++i) {
if(i in arr) {
reduced = reduceFunc(reduced, arr[i], i, arr);
}
}
return reduced;
};
function identity(x) {
return x;
}
function crash(fatalError) {
if(typeof monitorApi.reportUnhandled === 'function') {
monitorApi.reportUnhandled();
} else {
enqueue(function() {
throw fatalError;
});
}
throw fatalError;
}
return when;
});
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc