promised-utils.js | |
---|---|
'use strict' | |
Module exports set of of utility functions that are useful for working with promises. | var Q = require('q'), when = Q.when, defer = Q.defer
, _slice = Array.prototype.slice
, _forEach = Array.prototype.forEach |
allFunction takes array of promises and gives a new promise in return which will be fulfilled with an array of resolved promises that where passed. If any of the passed promises will get rejected, rejection will be forwarded to a returned promise. | /**
* Creates promise for array of the promises that is resolved with an array
* of the promise resolutions.
* @param {Promise[]} promises
* Array of promises to create promise for.
*/
function all(promises) {
var l = promises.length
, values = [] |
If empty array is passed to the function it is returned immediately. | if (0 == l) return values
var deferred = defer() |
Listeners are set for all the promises that where passed. | _forEach.call(promises, function(promise, index) {
when
( promise
, function resolved(value) { |
Resolved promises are stored in the array in the same exact order as they where passed to the function. | values[index] = value |
If all the observed promises are resolved resulting promise is resolved with an array of resolved promises. | if (0 === --l) deferred.resolve(values)
} |
If for some reason one of the promises is rejected, resulting promise is rejected with a same reason. | , function rejected(reason) { deferred.reject(reason) }
)
})
return deferred.promise
} |
Example: | exports.all = all |
PromisedFunction takes function as an argument. Optional second argument can be passed with a truthy value to make clear that function passed as a first argument is synchronous. | /**
* @param {Function} callee
* @returns {Promise}
*/
function Promised(callee, sync) { |
Passed function is wrapped into another, so called promised function, that is returned as a result. | return function promised() { |
Returned function always returns a new promise when called. | var deferred = defer()
, reject = Reject(deferred, callee) |
It also assumes that all of the arguments passed to it represent promises. | , possiblyPromises = _slice.call(arguments, 0) |
In addition | possiblyPromises.unshift(this) |
When all the possible promises are resolved, wrapped function is called | when
( all(possiblyPromises) |
It is called with resolved promises as an arguments. | , function possiblePromisesResolved(params) {
try { |
If wrapped function was not identified as synchronous one additional argument, callback function is passed to it. | if (!sync) params.push(Callback(deferred)) |
Resolved | var value = callee.call.apply(callee, params) |
If value returned by wrapped function was different from
| if (sync || undefined !== value) deferred.resolve(value)
} catch(error) { |
If exception is thrown by wrapper function returned promise is rejected with it. | reject(error)
}
} |
If for some reason one of the promises gets rejected, returned promise will be rejected with same reason, but with additional details. | , reject
)
return deferred.promise
}
} |
Example: | exports.Promised = Promised |
Promised.asyncAt the moment functions wrapped by | Promised.async = Promised |
Promised.syncAs it was mentioned above | Promised.sync = function syncPromised(callee) {
return Promised(callee, true)
} |
Example: | |
RejectFunction takes deferred promise and function performing operation that may throw an exception that should result in rejection of promise. | function Reject(deferred, callee) { |
Callback function is returned as a result value. | return function reject(reason) { |
If callback is called wrapped promise is rejected with: | deferred.reject( |
| { at: callee.name |
| , cause: reason |
| , stack: new Error(callee.name).stack
})
}
} |
CallbackFunction takes deferred promise and returns node.js style callback function. | /**
* @param {Deferred}
* @returns {Function}
*/
function Callback(deferred) {
return function callback(error, value) { |
If returned callback is called with first non-falsy argument, wrapped promise is rejected with it. | if (error) deferred.reject(error) |
Otherwise promise is resolved with a value of a second argument. | else deferred.resolve(value)
}
}
exports.Callback = Callback |
Example: | |