You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
3.7 KiB
104 lines
3.7 KiB
/** @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); }); |
|
|
|
|
|
|