105 lines
3.7 KiB
JavaScript
105 lines
3.7 KiB
JavaScript
/** @license MIT License (c) copyright 2013-2014 original author or authors */
|
|
|
|
/**
|
|
* Collection of helper functions for wrapping and executing 'traditional'
|
|
* synchronous functions in a promise interface.
|
|
*
|
|
* @author Brian Cavalier
|
|
* @contributor Renato Zannon
|
|
*/
|
|
|
|
(function(define) {
|
|
define(function(require) {
|
|
|
|
var when = require('./when');
|
|
var attempt = when['try'];
|
|
var _liftAll = require('./lib/liftAll');
|
|
var _apply = require('./lib/apply')(when.Promise);
|
|
var slice = Array.prototype.slice;
|
|
|
|
return {
|
|
lift: lift,
|
|
liftAll: liftAll,
|
|
call: attempt,
|
|
apply: apply,
|
|
compose: compose
|
|
};
|
|
|
|
/**
|
|
* Takes a function and an optional array of arguments (that might be promises),
|
|
* and calls the function. The return value is a promise whose resolution
|
|
* depends on the value returned by the function.
|
|
* @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(f, args) {
|
|
// slice args just in case the caller passed an Arguments instance
|
|
return _apply(f, this, args == null ? [] : slice.call(args));
|
|
}
|
|
|
|
/**
|
|
* Takes a 'regular' function and returns a version of that function that
|
|
* returns a promise instead of a plain value, and handles thrown errors by
|
|
* returning a rejected promise. Also accepts a list of arguments to be
|
|
* prepended to the new function, as does Function.prototype.bind.
|
|
*
|
|
* The resulting function is promise-aware, in the sense that it accepts
|
|
* promise arguments, and waits for their resolution.
|
|
* @param {Function} f function to be bound
|
|
* @param {...*} [args] arguments to be prepended for the new function @deprecated
|
|
* @returns {Function} a promise-returning function
|
|
*/
|
|
function lift(f /*, args... */) {
|
|
var args = arguments.length > 1 ? slice.call(arguments, 1) : [];
|
|
return function() {
|
|
return _apply(f, this, args.concat(slice.call(arguments)));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
* transparent to whether the functions return 'regular' values or promises:
|
|
* the piped argument is always a resolved value. If one of the functions
|
|
* throws or returns a rejected promise, the composed promise will be also
|
|
* rejected.
|
|
*
|
|
* The arguments (or promises to arguments) given to the returned function (if
|
|
* any), are passed directly to the first function on the 'pipeline'.
|
|
* @param {Function} f the function to which the arguments will be passed
|
|
* @param {...Function} [funcs] functions that will be composed, in order
|
|
* @returns {Function} a promise-returning composition of the functions
|
|
*/
|
|
function compose(f /*, funcs... */) {
|
|
var funcs = slice.call(arguments, 1);
|
|
|
|
return function() {
|
|
var thisArg = this;
|
|
var args = slice.call(arguments);
|
|
var firstPromise = attempt.apply(thisArg, [f].concat(args));
|
|
|
|
return when.reduce(funcs, function(arg, func) {
|
|
return func.call(thisArg, arg);
|
|
}, firstPromise);
|
|
};
|
|
}
|
|
});
|
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
|
|
|
|
|