Blame view

node_modules/when/function.js 3.75 KB
ce4c83ff   wxy   初始提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  /** @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); });