Comparing version 0.3.1 to 0.3.2
@@ -1,2 +0,2 @@ | ||
var Promise, isArray, isFunction, isNumber, isObject, utils, | ||
var Promise, isArray, isFunction, isNumber, utils, | ||
slice = [].slice; | ||
@@ -18,6 +18,2 @@ | ||
isObject = function(obj) { | ||
return typeof obj === 'object'; | ||
}; | ||
utils = module.exports = { | ||
@@ -77,3 +73,3 @@ | ||
async: function(limit, list, saveResults, progress) { | ||
var isIterDone, iter, iterIndex, resutls, running; | ||
var isIterDone, iter, iterIndex, resutls, running, tryIter; | ||
resutls = []; | ||
@@ -112,2 +108,11 @@ running = 0; | ||
} | ||
tryIter = function() { | ||
var e; | ||
try { | ||
return iter(); | ||
} catch (_error) { | ||
e = _error; | ||
return Promise.reject(e); | ||
} | ||
}; | ||
return new Promise(function(resolve, reject) { | ||
@@ -117,3 +122,3 @@ var addTask, allDone, i, results; | ||
var index, p, task; | ||
task = iter(); | ||
task = tryIter(); | ||
index = iterIndex++; | ||
@@ -304,9 +309,4 @@ if (isIterDone || task === utils.end) { | ||
return preFn.then(function(val) { | ||
var err, fn; | ||
try { | ||
fn = iter(val); | ||
} catch (_error) { | ||
err = _error; | ||
return Promise.reject(err); | ||
} | ||
var fn; | ||
fn = iter(val); | ||
if (fn === utils.end) { | ||
@@ -328,3 +328,3 @@ return val; | ||
isPromise: function(obj) { | ||
return isObject(obj) && isFunction(obj.then); | ||
return obj && isFunction(obj.then); | ||
}, | ||
@@ -331,0 +331,0 @@ |
1199
lib/yaku.js
/* | ||
Yaku v0.3.1 | ||
Yaku v0.3.2 | ||
(c) 2015 Yad Smood. http://ysmood.org | ||
License MIT | ||
*/ | ||
(function() { | ||
var Yaku; | ||
return Yaku = (function() { | ||
'use strict'; | ||
var $circularChain, $fromPrevious, $invalid_argument, $nil, $noop, $pending, $promiseTrace, $rejected, $resolved, $settlerTrace, $tryCatchFn, $tryErr, addHandler, assertIterable, callHanler, genScheduler, genSettler, genStackInfo, genTraceInfo, genTryCatcher, genTypeError, getThen, isFunction, isLongStackTrace, isObject, newEmptyYaku, release, root, scheduleHandler, scheduleUnhandledRejection, settlePromise, settleWithX, settleXthen, tryCatcher; | ||
var Yaku; | ||
$nil = void 0; | ||
Yaku = (function() { | ||
'use strict'; | ||
var $circularChain, $fromPrevious, $invalid_argument, $nil, $noop, $pending, $promiseTrace, $rejected, $resolved, $settlerTrace, $tryCatchFn, $tryErr, addHandler, assertIterable, callHanler, genScheduler, genSettler, genStackInfo, genTraceInfo, genTryCatcher, genTypeError, getThen, hashOnRejected, isFunction, isLongStackTrace, isObject, newEmptyYaku, root, scheduleHandler, scheduleUnhandledRejection, settlePromise, settleWithX, settleXthen, tryCatcher; | ||
root = typeof global === 'object' ? global : window; | ||
$nil = void 0; | ||
root = typeof global === 'object' ? global : window; | ||
/** | ||
* This class follows the [Promises/A+](https://promisesaplus.com) and | ||
* [ES6](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects) spec | ||
* with some extra helpers. | ||
* @param {Function} executor Function object with two arguments resolve and reject. | ||
* The first argument fulfills the promise, the second argument rejects it. | ||
* We can call these functions, once our operation is completed. | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* p = new Promise (resolve, reject) -> | ||
* setTimeout -> | ||
* if Math.random() > 0.5 | ||
* resolve 'ok' | ||
* else | ||
* reject 'no' | ||
* ``` | ||
*/ | ||
function Yaku(executor) { | ||
var err; | ||
if (isLongStackTrace) { | ||
this[$promiseTrace] = genTraceInfo(); | ||
} | ||
if (executor === $noop) { | ||
return; | ||
} | ||
err = genTryCatcher(executor)(genSettler(this, $resolved), genSettler(this, $rejected)); | ||
if (err === $tryErr) { | ||
settlePromise(this, $rejected, err.e); | ||
} | ||
/** | ||
* This class follows the [Promises/A+](https://promisesaplus.com) and | ||
* [ES6](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects) spec | ||
* with some extra helpers. | ||
* @param {Function} executor Function object with three arguments resolve, reject and | ||
* the promise itself. | ||
* The first argument fulfills the promise, the second argument rejects it. | ||
* We can call these functions, once our operation is completed. | ||
* The third argument can be used to add custom handlers, such as `abort` or `progress` | ||
* helpers. | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* p = new Promise (resolve, reject, self) -> | ||
* self.abort = -> | ||
* clearTimeout tmr | ||
* reject new Error 'abort promise' | ||
* | ||
* tmr = setTimeout -> | ||
* if Math.random() > 0.5 | ||
* resolve 'ok' | ||
* else | ||
* reject 'no' | ||
* , 3000 | ||
* p.abort() | ||
* ``` | ||
*/ | ||
function Yaku(executor) { | ||
var err, self; | ||
self = this; | ||
if (isLongStackTrace) { | ||
self[$promiseTrace] = genTraceInfo(); | ||
} | ||
if (executor === $noop) { | ||
return; | ||
} | ||
err = genTryCatcher(executor)(genSettler(self, $resolved), genSettler(self, $rejected), self); | ||
if (err === $tryErr) { | ||
settlePromise(self, $rejected, err.e); | ||
} | ||
} | ||
/** | ||
* Appends fulfillment and rejection handlers to the promise, | ||
* and returns a new promise resolving to the return value of the called handler. | ||
* @param {Function} onFulfilled Optional. Called when the Promise is resolved. | ||
* @param {Function} onRejected Optional. Called when the Promise is rejected. | ||
* @return {Yaku} It will return a new Yaku which will resolve or reject after | ||
* @example | ||
* the current Promise. | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* p = Promise.resolve 10 | ||
* | ||
* p.then (v) -> | ||
* console.log v | ||
* ``` | ||
*/ | ||
/** | ||
* Appends fulfillment and rejection handlers to the promise, | ||
* and returns a new promise resolving to the return value of the called handler. | ||
* @param {Function} onFulfilled Optional. Called when the Promise is resolved. | ||
* @param {Function} onRejected Optional. Called when the Promise is rejected. | ||
* @return {Yaku} It will return a new Yaku which will resolve or reject after | ||
* @example | ||
* the current Promise. | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* p = Promise.resolve 10 | ||
* | ||
* p.then (v) -> | ||
* console.log v | ||
* ``` | ||
*/ | ||
Yaku.prototype.then = function(onFulfilled, onRejected) { | ||
return addHandler(this, newEmptyYaku(), onFulfilled, onRejected); | ||
}; | ||
Yaku.prototype.then = function(onFulfilled, onRejected) { | ||
return addHandler(this, newEmptyYaku(), onFulfilled, onRejected); | ||
}; | ||
/** | ||
* The `catch()` method returns a Promise and deals with rejected cases only. | ||
* It behaves the same as calling `Promise.prototype.then(undefined, onRejected)`. | ||
* @param {Function} onRejected A Function called when the Promise is rejected. | ||
* This function has one argument, the rejection reason. | ||
* @return {Yaku} A Promise that deals with rejected cases only. | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* p = Promise.reject 10 | ||
* | ||
* p.catch (v) -> | ||
* console.log v | ||
* ``` | ||
*/ | ||
/** | ||
* The `catch()` method returns a Promise and deals with rejected cases only. | ||
* It behaves the same as calling `Promise.prototype.then(undefined, onRejected)`. | ||
* @param {Function} onRejected A Function called when the Promise is rejected. | ||
* This function has one argument, the rejection reason. | ||
* @return {Yaku} A Promise that deals with rejected cases only. | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* p = Promise.reject 10 | ||
* | ||
* p.catch (v) -> | ||
* console.log v | ||
* ``` | ||
*/ | ||
Yaku.prototype["catch"] = function(onRejected) { | ||
return this.then($nil, onRejected); | ||
}; | ||
Yaku.prototype["catch"] = function(onRejected) { | ||
return this.then($nil, onRejected); | ||
}; | ||
/** | ||
* The `Promise.resolve(value)` method returns a Promise object that is resolved with the given value. | ||
* If the value is a thenable (i.e. has a then method), the returned promise will "follow" that thenable, | ||
* adopting its eventual state; otherwise the returned promise will be fulfilled with the value. | ||
* @param {Any} value Argument to be resolved by this Promise. | ||
* Can also be a Promise or a thenable to resolve. | ||
* @return {Yaku} | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* p = Promise.resolve 10 | ||
* ``` | ||
*/ | ||
/** | ||
* The `Promise.resolve(value)` method returns a Promise object that is resolved with the given value. | ||
* If the value is a thenable (i.e. has a then method), the returned promise will "follow" that thenable, | ||
* adopting its eventual state; otherwise the returned promise will be fulfilled with the value. | ||
* @param {Any} value Argument to be resolved by this Promise. | ||
* Can also be a Promise or a thenable to resolve. | ||
* @return {Yaku} | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* p = Promise.resolve 10 | ||
* ``` | ||
*/ | ||
Yaku.resolve = function(value) { | ||
if (value instanceof Yaku) { | ||
return value; | ||
} | ||
return settleWithX(newEmptyYaku(), value); | ||
}; | ||
Yaku.resolve = function(value) { | ||
if (value instanceof Yaku) { | ||
return value; | ||
} | ||
return settleWithX(newEmptyYaku(), value); | ||
}; | ||
/** | ||
* The `Promise.reject(reason)` method returns a Promise object that is rejected with the given reason. | ||
* @param {Any} reason Reason why this Promise rejected. | ||
* @return {Yaku} | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* p = Promise.reject 10 | ||
* ``` | ||
*/ | ||
/** | ||
* The `Promise.reject(reason)` method returns a Promise object that is rejected with the given reason. | ||
* @param {Any} reason Reason why this Promise rejected. | ||
* @return {Yaku} | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* p = Promise.reject 10 | ||
* ``` | ||
*/ | ||
Yaku.reject = function(reason) { | ||
return settlePromise(newEmptyYaku(), $rejected, reason); | ||
}; | ||
Yaku.reject = function(reason) { | ||
return settlePromise(newEmptyYaku(), $rejected, reason); | ||
}; | ||
/** | ||
* The `Promise.race(iterable)` method returns a promise that resolves or rejects | ||
* as soon as one of the promises in the iterable resolves or rejects, | ||
* with the value or reason from that promise. | ||
* @param {iterable} iterable An iterable object, such as an Array. | ||
* @return {Yaku} The race function returns a Promise that is settled | ||
* the same way as the first passed promise to settle. | ||
* It resolves or rejects, whichever happens first. | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* Promise.race [ | ||
* 123 | ||
* Promise.resolve 0 | ||
* ] | ||
* .then (value) -> | ||
* console.log value # => 123 | ||
* ``` | ||
*/ | ||
/** | ||
* The `Promise.race(iterable)` method returns a promise that resolves or rejects | ||
* as soon as one of the promises in the iterable resolves or rejects, | ||
* with the value or reason from that promise. | ||
* @param {iterable} iterable An iterable object, such as an Array. | ||
* @return {Yaku} The race function returns a Promise that is settled | ||
* the same way as the first passed promise to settle. | ||
* It resolves or rejects, whichever happens first. | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* Promise.race [ | ||
* 123 | ||
* Promise.resolve 0 | ||
* ] | ||
* .then (value) -> | ||
* console.log value # => 123 | ||
* ``` | ||
*/ | ||
Yaku.race = function(iterable) { | ||
var i, len, p; | ||
assertIterable(iterable); | ||
len = iterable.length; | ||
if (len === 0) { | ||
return Yaku.resolve([]); | ||
Yaku.race = function(iterable) { | ||
var i, len, p; | ||
assertIterable(iterable); | ||
len = iterable.length; | ||
if (len === 0) { | ||
return Yaku.resolve([]); | ||
} | ||
p = newEmptyYaku(); | ||
i = 0; | ||
while (i < len) { | ||
settleWithX(p, iterable[i++]); | ||
if (p._state !== $pending) { | ||
break; | ||
} | ||
p = newEmptyYaku(); | ||
i = 0; | ||
while (i < len) { | ||
settleWithX(p, iterable[i++]); | ||
if (p._state !== $pending) { | ||
break; | ||
} | ||
return p; | ||
}; | ||
/** | ||
* The `Promise.all(iterable)` method returns a promise that resolves when | ||
* all of the promises in the iterable argument have resolved. | ||
* | ||
* The result is passed as an array of values from all the promises. | ||
* If something passed in the iterable array is not a promise, | ||
* it's converted to one by Promise.resolve. If any of the passed in promises rejects, | ||
* the all Promise immediately rejects with the value of the promise that rejected, | ||
* discarding all the other promises whether or not they have resolved. | ||
* @param {iterable} iterable An iterable object, such as an Array. | ||
* @return {Yaku} | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* Promise.all [ | ||
* 123 | ||
* Promise.resolve 0 | ||
* ] | ||
* .then (values) -> | ||
* console.log values # => [123, 0] | ||
* ``` | ||
*/ | ||
Yaku.all = function(iterable) { | ||
var convertor, countDown, i, iter, len, onRejected, p1, res; | ||
assertIterable(iterable); | ||
convertor = Yaku.resolve; | ||
len = countDown = iterable.length; | ||
if (len === 0) { | ||
return convertor([]); | ||
} | ||
p1 = newEmptyYaku(); | ||
res = []; | ||
i = 0; | ||
onRejected = function(reason) { | ||
settlePromise(p1, $rejected, reason); | ||
}; | ||
iter = function(i) { | ||
convertor(iterable[i]).then(function(value) { | ||
res[i] = value; | ||
if (!--countDown) { | ||
settlePromise(p1, $resolved, res); | ||
} | ||
} | ||
return p; | ||
}, onRejected); | ||
}; | ||
while (i < len) { | ||
iter(i++); | ||
} | ||
return p1; | ||
}; | ||
/** | ||
* The `Promise.all(iterable)` method returns a promise that resolves when | ||
* all of the promises in the iterable argument have resolved. | ||
* | ||
* The result is passed as an array of values from all the promises. | ||
* If something passed in the iterable array is not a promise, | ||
* it's converted to one by Promise.resolve. If any of the passed in promises rejects, | ||
* the all Promise immediately rejects with the value of the promise that rejected, | ||
* discarding all the other promises whether or not they have resolved. | ||
* @param {iterable} iterable An iterable object, such as an Array. | ||
* @return {Yaku} | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* Promise.all [ | ||
* 123 | ||
* Promise.resolve 0 | ||
* ] | ||
* .then (values) -> | ||
* console.log values # => [123, 0] | ||
* ``` | ||
*/ | ||
/** | ||
* Catch all possibly unhandled rejections. If you want to use specific | ||
* format to display the error stack, overwrite it. | ||
* If it is set, auto `console.error` unhandled rejection will be disabed. | ||
* @param {Any} reason The rejection reason. | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* Promise.onUnhandledRejection = (reason) -> | ||
* console.error reason | ||
* | ||
* # The console will log an unhandled rejection error message. | ||
* Promise.reject('my reason') | ||
* | ||
* # The below won't log the unhandled rejection error message. | ||
* Promise.reject('v').catch -> | ||
* ``` | ||
*/ | ||
Yaku.all = function(iterable) { | ||
var convertor, countDown, i, iter, len, onRejected, p1, res; | ||
assertIterable(iterable); | ||
convertor = Yaku.resolve; | ||
len = countDown = iterable.length; | ||
if (len === 0) { | ||
return convertor([]); | ||
} | ||
p1 = newEmptyYaku(); | ||
res = []; | ||
i = 0; | ||
onRejected = function(reason) { | ||
settlePromise(p1, $rejected, reason); | ||
}; | ||
iter = function(i) { | ||
convertor(iterable[i]).then(function(value) { | ||
res[i] = value; | ||
if (!--countDown) { | ||
settlePromise(p1, $resolved, res); | ||
} | ||
}, onRejected); | ||
}; | ||
while (i < len) { | ||
iter(i++); | ||
} | ||
return p1; | ||
}; | ||
Yaku.onUnhandledRejection = function(reason, p) { | ||
var info; | ||
if (!isObject(console)) { | ||
return; | ||
} | ||
info = genStackInfo(reason, p); | ||
return console.error('Unhandled Rejection:', info[0], info[1]); | ||
}; | ||
isLongStackTrace = false; | ||
/** | ||
* Catch all possibly unhandled rejections. If you want to use specific | ||
* format to display the error stack, overwrite it. | ||
* If it is set, auto `console.error` unhandled rejection will be disabed. | ||
* @param {Any} reason The rejection reason. | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* Promise.onUnhandledRejection = (reason) -> | ||
* console.error reason | ||
* | ||
* # The console will log an unhandled rejection error message. | ||
* Promise.reject('my reason') | ||
* | ||
* # The below won't log the unhandled rejection error message. | ||
* Promise.reject('v').catch -> | ||
* ``` | ||
*/ | ||
Yaku.onUnhandledRejection = function(reason, p) { | ||
var info; | ||
if (!isObject(console)) { | ||
return; | ||
} | ||
info = genStackInfo(reason, p); | ||
return console.error('Unhandled Rejection:', info[0], info[1]); | ||
}; | ||
/** | ||
* It is used to enable the long stack trace. | ||
* Once it is enabled, it can't be reverted. | ||
* While it is very helpful in development and testing environments, | ||
* it is not recommended to use it in production. It will slow down your | ||
* application and waste your memory. | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* Promise.enableLongStackTrace() | ||
* ``` | ||
*/ | ||
isLongStackTrace = false; | ||
Yaku.enableLongStackTrace = function() { | ||
isLongStackTrace = true; | ||
}; | ||
/** | ||
* It is used to enable the long stack trace. | ||
* Once it is enabled, it can't be reverted. | ||
* While it is very helpful in development and testing environments, | ||
* it is not recommended to use it in production. It will slow down your | ||
* application and waste your memory. | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* Promise.enableLongStackTrace() | ||
* ``` | ||
*/ | ||
/** | ||
* Only Node has `process.nextTick` function. For browser there are | ||
* so many ways to polyfill it. Yaku won't do it for you, instead you | ||
* can choose what you prefer. For example, this project | ||
* [setImmediate](https://github.com/YuzuJS/setImmediate). | ||
* By default, Yaku will use `process.nextTick` on Node, `setTimeout` on browser. | ||
* @type {Function} | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* Promise.nextTick = window.setImmediate | ||
* ``` | ||
*/ | ||
Yaku.enableLongStackTrace = function() { | ||
isLongStackTrace = true; | ||
}; | ||
Yaku.nextTick = $nil; | ||
/** | ||
* Only Node has `process.nextTick` function. For browser there are | ||
* so many ways to polyfill it. Yaku won't do it for you, instead you | ||
* can choose what you prefer. For example, this project | ||
* [setImmediate](https://github.com/YuzuJS/setImmediate). | ||
* By default, Yaku will use `process.nextTick` on Node, `setTimeout` on browser. | ||
* @type {Function} | ||
* @example | ||
* ```coffee | ||
* Promise = require 'yaku' | ||
* Promise.nextTick = window.setImmediate | ||
* ``` | ||
*/ | ||
/* | ||
* All static variable name will begin with `$`. Such as `$rejected`. | ||
* @private | ||
*/ | ||
Yaku.nextTick = $nil; | ||
$tryCatchFn = null; | ||
$tryErr = { | ||
e: null | ||
}; | ||
/* | ||
* All static variable name will begin with `$`. Such as `$rejected`. | ||
* @private | ||
*/ | ||
$noop = {}; | ||
$tryCatchFn = null; | ||
isObject = function(obj) { | ||
return typeof obj === 'object'; | ||
}; | ||
$tryErr = { | ||
e: null | ||
}; | ||
isFunction = function(obj) { | ||
return typeof obj === 'function'; | ||
}; | ||
$noop = {}; | ||
isObject = function(obj) { | ||
return typeof obj === 'object'; | ||
}; | ||
/** | ||
* Wrap a function into a try-catch. | ||
* @private | ||
* @return {Any | $tryErr} | ||
*/ | ||
isFunction = function(obj) { | ||
return typeof obj === 'function'; | ||
}; | ||
tryCatcher = function() { | ||
var e; | ||
try { | ||
return $tryCatchFn.apply(this, arguments); | ||
} catch (_error) { | ||
e = _error; | ||
$tryErr.e = e; | ||
return $tryErr; | ||
} | ||
}; | ||
/** | ||
* Release the specified key of an object. | ||
* @private | ||
* @param {Object} obj | ||
* @param {String | Number} key | ||
*/ | ||
/** | ||
* Generate a try-catch wrapped function. | ||
* @private | ||
* @param {Function} fn | ||
* @return {Function} | ||
*/ | ||
release = function(obj, key) { | ||
obj[key] = $nil; | ||
}; | ||
genTryCatcher = function(fn) { | ||
$tryCatchFn = fn; | ||
return tryCatcher; | ||
}; | ||
/** | ||
* Wrap a function into a try-catch. | ||
* @private | ||
* @return {Any | $tryErr} | ||
*/ | ||
/** | ||
* Generate a scheduler. | ||
* @private | ||
* @param {Integer} initQueueSize | ||
* @param {Function} fn `(Yaku, Value) ->` The schedule handler. | ||
* @return {Function} `(Yaku, Value) ->` The scheduler. | ||
*/ | ||
tryCatcher = function() { | ||
var e; | ||
try { | ||
return $tryCatchFn.apply(this, arguments); | ||
} catch (_error) { | ||
e = _error; | ||
$tryErr.e = e; | ||
return $tryErr; | ||
} | ||
}; | ||
genScheduler = function(initQueueSize, fn) { | ||
/** | ||
* Generate a try-catch wrapped function. | ||
* @private | ||
* @param {Function} fn | ||
* @return {Function} | ||
* All async promise will be scheduled in | ||
* here, so that they can be execute on the next tick. | ||
* @private | ||
*/ | ||
var flush, fnQueue, fnQueueLen; | ||
fnQueue = Array(initQueueSize); | ||
fnQueueLen = 0; | ||
genTryCatcher = function(fn) { | ||
$tryCatchFn = fn; | ||
return tryCatcher; | ||
}; | ||
/** | ||
* Generate a scheduler. | ||
* @private | ||
* @param {Integer} initQueueSize | ||
* @param {Function} fn `(Yaku, Value) ->` The schedule handler. | ||
* @return {Function} `(Yaku, Value) ->` The scheduler. | ||
* Run all queued functions. | ||
* @private | ||
*/ | ||
genScheduler = function(initQueueSize, fn) { | ||
/** | ||
* All async promise will be scheduled in | ||
* here, so that they can be execute on the next tick. | ||
* @private | ||
*/ | ||
var flush, fnQueue, fnQueueLen; | ||
fnQueue = Array(initQueueSize); | ||
flush = function() { | ||
var i; | ||
i = 0; | ||
while (i < fnQueueLen) { | ||
fn(fnQueue[i]); | ||
fnQueue[i++] = $nil; | ||
} | ||
fnQueueLen = 0; | ||
/** | ||
* Run all queued functions. | ||
* @private | ||
*/ | ||
flush = function() { | ||
var i, p, pIndex, v, vIndex; | ||
i = 0; | ||
while (i < fnQueueLen) { | ||
pIndex = i++; | ||
vIndex = i++; | ||
p = fnQueue[pIndex]; | ||
v = fnQueue[vIndex]; | ||
release(fnQueue, pIndex); | ||
release(fnQueue, vIndex); | ||
fn(p, v); | ||
} | ||
fnQueueLen = 0; | ||
if (fnQueue.length > initQueueSize) { | ||
fnQueue.length = initQueueSize; | ||
}; | ||
/** | ||
* Schedule a flush task on the next tick. | ||
* @private | ||
* @param {Function} fn The flush task. | ||
*/ | ||
Yaku.nextTick = (function() { | ||
try { | ||
return root.process.nextTick; | ||
} catch (_error) { | ||
return setTimeout; | ||
} | ||
})(); | ||
return function(p, v) { | ||
fnQueue[fnQueueLen++] = p; | ||
fnQueue[fnQueueLen++] = v; | ||
if (fnQueueLen === 2) { | ||
Yaku.nextTick(flush); | ||
} | ||
}; | ||
} | ||
}; | ||
/** | ||
* Check if a variable is an iterable object. | ||
* @private | ||
* @param {Any} obj | ||
* @return {Boolean} | ||
* Schedule a flush task on the next tick. | ||
* @private | ||
* @param {Function} fn The flush task. | ||
*/ | ||
assertIterable = function(obj) { | ||
if (obj instanceof Array) { | ||
return; | ||
Yaku.nextTick = (function() { | ||
try { | ||
return root.process.nextTick; | ||
} catch (_error) { | ||
return setTimeout.bind(root); | ||
} | ||
throw genTypeError($invalid_argument); | ||
})(); | ||
return function(v) { | ||
fnQueue[fnQueueLen++] = v; | ||
if (fnQueueLen === 1) { | ||
Yaku.nextTick(flush); | ||
} | ||
}; | ||
}; | ||
/** | ||
* Generate type error object. | ||
* @private | ||
* @param {String} msg | ||
* @return {TypeError} | ||
*/ | ||
/** | ||
* Check if a variable is an iterable object. | ||
* @private | ||
* @param {Any} obj | ||
* @return {Boolean} | ||
*/ | ||
genTypeError = function(msg) { | ||
return new TypeError(msg); | ||
}; | ||
assertIterable = function(obj) { | ||
if (obj instanceof Array) { | ||
return; | ||
} | ||
throw genTypeError($invalid_argument); | ||
}; | ||
genTraceInfo = function(noTitle) { | ||
return (new Error).stack.replace('Error', (noTitle ? '' : $fromPrevious)); | ||
}; | ||
/** | ||
* Generate type error object. | ||
* @private | ||
* @param {String} msg | ||
* @return {TypeError} | ||
*/ | ||
/** | ||
* These are some static symbolys. | ||
* @private | ||
*/ | ||
genTypeError = function(msg) { | ||
return new TypeError(msg); | ||
}; | ||
$rejected = 0; | ||
genTraceInfo = function(noTitle) { | ||
return (new Error).stack.replace('Error', (noTitle ? '' : $fromPrevious)); | ||
}; | ||
$resolved = 1; | ||
$pending = 2; | ||
/** | ||
* These are some static symbolys. | ||
* @private | ||
*/ | ||
$promiseTrace = '_pStack'; | ||
$rejected = 0; | ||
$settlerTrace = '_sStack'; | ||
$resolved = 1; | ||
$circularChain = 'promise_circular_chain'; | ||
$pending = 2; | ||
$invalid_argument = 'invalid_argument'; | ||
$promiseTrace = '_pStack'; | ||
$fromPrevious = 'From previous event:'; | ||
$settlerTrace = '_sStack'; | ||
Yaku.prototype._state = $pending; | ||
$circularChain = 'promise_circular_chain'; | ||
$invalid_argument = 'invalid_argument'; | ||
/** | ||
* The number of current promises that attach to this Yaku instance. | ||
* @private | ||
*/ | ||
$fromPrevious = 'From previous event:'; | ||
Yaku.prototype._pCount = 0; | ||
Yaku.prototype._state = $pending; | ||
Yaku.prototype._pre = null; | ||
/** | ||
* The number of current promises that attach to this Yaku instance. | ||
* @private | ||
*/ | ||
/** | ||
* Create an empty promise. | ||
* @private | ||
* @return {Yaku} | ||
*/ | ||
Yaku.prototype._pCount = 0; | ||
newEmptyYaku = function() { | ||
return new Yaku($noop); | ||
}; | ||
Yaku.prototype._pre = null; | ||
/** | ||
* It will produce a settlePromise function to user. | ||
* Such as the resolve and reject in this `new Yaku (resolve, reject) ->`. | ||
* @private | ||
* @param {Yaku} self | ||
* @param {Integer} state The value is one of `$pending`, `$resolved` or `$rejected`. | ||
* @return {Function} `(value) -> undefined` A resolve or reject function. | ||
*/ | ||
/** | ||
* Create an empty promise. | ||
* @private | ||
* @return {Yaku} | ||
*/ | ||
genSettler = function(self, state) { | ||
return function(value) { | ||
if (isLongStackTrace) { | ||
self[$settlerTrace] = genTraceInfo(true); | ||
} | ||
if (state === $resolved) { | ||
settleWithX(self, value); | ||
} else { | ||
settlePromise(self, state, value); | ||
} | ||
}; | ||
}; | ||
newEmptyYaku = function() { | ||
return new Yaku($noop); | ||
}; | ||
/** | ||
* Link the promise1 to the promise2. | ||
* @private | ||
* @param {Yaku} p1 | ||
* @param {Yaku} p2 | ||
* @param {Function} onFulfilled | ||
* @param {Function} onRejected | ||
*/ | ||
/** | ||
* It will produce a settlePromise function to user. | ||
* Such as the resolve and reject in this `new Yaku (resolve, reject) ->`. | ||
* @private | ||
* @param {Yaku} self | ||
* @param {Integer} state The value is one of `$pending`, `$resolved` or `$rejected`. | ||
* @return {Function} `(value) -> undefined` A resolve or reject function. | ||
*/ | ||
addHandler = function(p1, p2, onFulfilled, onRejected) { | ||
if (isFunction(onFulfilled)) { | ||
p2._onFulfilled = onFulfilled; | ||
genSettler = function(self, state) { | ||
return function(value) { | ||
if (isLongStackTrace) { | ||
self[$settlerTrace] = genTraceInfo(true); | ||
} | ||
if (isFunction(onRejected)) { | ||
p2._onRejected = onRejected; | ||
if (state === $resolved) { | ||
settleWithX(self, value); | ||
} else { | ||
settlePromise(self, state, value); | ||
} | ||
p2._pre = p1; | ||
p1[p1._pCount++] = p2; | ||
if (p1._state !== $pending) { | ||
scheduleHandler(p1, p2); | ||
} | ||
return p2; | ||
}; | ||
}; | ||
/** | ||
* Resolve the value returned by onFulfilled or onRejected. | ||
* @private | ||
* @param {Yaku} p1 | ||
* @param {Yaku} p2 | ||
*/ | ||
/** | ||
* Link the promise1 to the promise2. | ||
* @private | ||
* @param {Yaku} p1 | ||
* @param {Yaku} p2 | ||
* @param {Function} onFulfilled | ||
* @param {Function} onRejected | ||
*/ | ||
scheduleHandler = genScheduler(999, function(p1, p2) { | ||
var handler, x; | ||
addHandler = function(p1, p2, onFulfilled, onRejected) { | ||
if (isFunction(onFulfilled)) { | ||
p2._onFulfilled = onFulfilled; | ||
} | ||
if (isFunction(onRejected)) { | ||
p2._onRejected = onRejected; | ||
} | ||
p2._pre = p1; | ||
p1[p1._pCount++] = p2; | ||
if (p1._state !== $pending && p1._pCount > 0) { | ||
scheduleHandler(p1); | ||
} | ||
return p2; | ||
}; | ||
/** | ||
* Resolve the value returned by onFulfilled or onRejected. | ||
* @private | ||
* @param {Yaku} p1 | ||
* @param {Yaku} p2 | ||
*/ | ||
scheduleHandler = genScheduler(999, function(p1) { | ||
var handler, i, len, p2, x; | ||
i = 0; | ||
len = p1._pCount; | ||
while (i < len) { | ||
p2 = p1[i++]; | ||
if (p2._state !== $pending) { | ||
continue; | ||
} | ||
handler = p1._state ? p2._onFulfilled : p2._onRejected; | ||
if (handler === $nil) { | ||
settlePromise(p2, p1._state, p1._value); | ||
return; | ||
continue; | ||
} | ||
@@ -556,195 +557,191 @@ x = genTryCatcher(callHanler)(handler, p1._value); | ||
settlePromise(p2, $rejected, x.e); | ||
return; | ||
continue; | ||
} | ||
settleWithX(p2, x); | ||
}); | ||
} | ||
}); | ||
scheduleUnhandledRejection = genScheduler(9, genScheduler(9, function(p) { | ||
var iter; | ||
iter = function(node) { | ||
var i, len; | ||
i = 0; | ||
len = node._pCount; | ||
if (node._onRejected) { | ||
return; | ||
} | ||
while (i < len) { | ||
if (!iter(node[i++])) { | ||
return; | ||
} | ||
} | ||
hashOnRejected = function(node) { | ||
var child, i, len; | ||
i = 0; | ||
len = node._pCount; | ||
while (i < len) { | ||
child = node[i++]; | ||
if (child._onRejected) { | ||
return true; | ||
}; | ||
if (iter(p)) { | ||
Yaku.onUnhandledRejection(p._value, p); | ||
} | ||
})); | ||
if (hashOnRejected(child)) { | ||
return true; | ||
} | ||
} | ||
}; | ||
genStackInfo = function(reason, p) { | ||
var clean, iter, push, stackInfo, stackStr, trim; | ||
stackInfo = []; | ||
trim = function(str) { | ||
return str.replace(/^\s+|\s+$/g, ''); | ||
scheduleUnhandledRejection = genScheduler(9, genScheduler(9, function(p) { | ||
if ((!p._pre || p._pre._state === $resolved) && !hashOnRejected(p)) { | ||
Yaku.onUnhandledRejection(p._value, p); | ||
} | ||
})); | ||
genStackInfo = function(reason, p) { | ||
var clean, iter, push, stackInfo, stackStr, trim; | ||
stackInfo = []; | ||
trim = function(str) { | ||
return str.replace(/^\s+|\s+$/g, ''); | ||
}; | ||
if (isLongStackTrace && p[$promiseTrace]) { | ||
push = function(trace) { | ||
return stackInfo.push(trim(trace)); | ||
}; | ||
if (isLongStackTrace && p[$promiseTrace]) { | ||
push = function(trace) { | ||
return stackInfo.push(trim(trace)); | ||
}; | ||
if (p[$settlerTrace]) { | ||
push(p[$settlerTrace]); | ||
} | ||
iter = function(node) { | ||
if (!node) { | ||
return; | ||
} | ||
iter(node._next); | ||
push(node[$promiseTrace]); | ||
return iter(node._pre); | ||
}; | ||
iter(p); | ||
if (p[$settlerTrace]) { | ||
push(p[$settlerTrace]); | ||
} | ||
stackStr = '\n' + stackInfo.join('\n'); | ||
clean = function(stack, cleanPrev) { | ||
var i; | ||
if (cleanPrev && (i = stack.indexOf('\n' + $fromPrevious)) > 0) { | ||
stack = stack.slice(0, i); | ||
iter = function(node) { | ||
if (!node) { | ||
return; | ||
} | ||
if (typeof __filename === 'string') { | ||
return stack.replace(RegExp(".+" + __filename + ".+\\n?", "g"), ''); | ||
} | ||
iter(node._next); | ||
push(node[$promiseTrace]); | ||
return iter(node._pre); | ||
}; | ||
return [(reason ? reason.stack ? clean(trim(reason.stack), true) : reason : reason), clean(stackStr)]; | ||
iter(p); | ||
} | ||
stackStr = '\n' + stackInfo.join('\n'); | ||
clean = function(stack, cleanPrev) { | ||
var i; | ||
if (cleanPrev && (i = stack.indexOf('\n' + $fromPrevious)) > 0) { | ||
stack = stack.slice(0, i); | ||
} | ||
if (typeof __filename === 'string') { | ||
return stack.replace(RegExp(".+" + __filename + ".+\\n?", "g"), ''); | ||
} | ||
}; | ||
return [(reason ? reason.stack ? clean(trim(reason.stack), true) : reason : reason), clean(stackStr)]; | ||
}; | ||
callHanler = function(handler, value) { | ||
return handler(value); | ||
}; | ||
callHanler = function(handler, value) { | ||
return handler(value); | ||
}; | ||
/** | ||
* Resolve or reject a promise. | ||
* @private | ||
* @param {Yaku} p | ||
* @param {Integer} state | ||
* @param {Any} value | ||
*/ | ||
/** | ||
* Resolve or reject a promise. | ||
* @private | ||
* @param {Yaku} p | ||
* @param {Integer} state | ||
* @param {Any} value | ||
*/ | ||
settlePromise = function(p, state, value) { | ||
var i, len, stack; | ||
if (p._state !== $pending) { | ||
return; | ||
settlePromise = function(p, state, value) { | ||
var stack; | ||
if (p._state !== $pending) { | ||
return; | ||
} | ||
p._state = state; | ||
p._value = value; | ||
if (state === $rejected) { | ||
if (isLongStackTrace && value && value.stack) { | ||
stack = genStackInfo(value, p); | ||
value.stack = stack[0] + stack[1]; | ||
} | ||
p._state = state; | ||
p._value = value; | ||
if (state === $rejected) { | ||
if (isLongStackTrace && value && value.stack) { | ||
stack = genStackInfo(value, p); | ||
value.stack = stack[0] + stack[1]; | ||
} | ||
if (!p._pre || p._pre._state === $resolved) { | ||
scheduleUnhandledRejection(p); | ||
} | ||
} | ||
if (!isLongStackTrace) { | ||
p._pre = $nil; | ||
} | ||
i = 0; | ||
len = p._pCount; | ||
while (i < len) { | ||
scheduleHandler(p, p[i++]); | ||
} | ||
return p; | ||
}; | ||
scheduleUnhandledRejection(p); | ||
} | ||
if (!isLongStackTrace) { | ||
p._pre = $nil; | ||
} | ||
if (p._pCount > 0) { | ||
scheduleHandler(p); | ||
} | ||
return p; | ||
}; | ||
/** | ||
* Resolve or reject primise with value x. The x can also be a thenable. | ||
* @private | ||
* @param {Yaku} p | ||
* @param {Any | Thenable} x A normal value or a thenable. | ||
*/ | ||
/** | ||
* Resolve or reject primise with value x. The x can also be a thenable. | ||
* @private | ||
* @param {Yaku} p | ||
* @param {Any | Thenable} x A normal value or a thenable. | ||
*/ | ||
settleWithX = function(p, x) { | ||
var xthen; | ||
if (x === p && x) { | ||
settlePromise(p, $rejected, genTypeError($circularChain)); | ||
settleWithX = function(p, x) { | ||
var xthen; | ||
if (x === p && x) { | ||
settlePromise(p, $rejected, genTypeError($circularChain)); | ||
return; | ||
} | ||
if (x !== null && (isFunction(x) || isObject(x))) { | ||
xthen = genTryCatcher(getThen)(x); | ||
if (xthen === $tryErr) { | ||
settlePromise(p, $rejected, xthen.e); | ||
return; | ||
} | ||
if (x !== null && (isFunction(x) || isObject(x))) { | ||
xthen = genTryCatcher(getThen)(x); | ||
if (xthen === $tryErr) { | ||
settlePromise(p, $rejected, xthen.e); | ||
return; | ||
if (isFunction(xthen)) { | ||
if (isLongStackTrace && x instanceof Yaku) { | ||
p._next = x; | ||
} | ||
if (isFunction(xthen)) { | ||
if (isLongStackTrace && x instanceof Yaku) { | ||
p._next = x; | ||
} | ||
settleXthen(p, x, xthen); | ||
} else { | ||
settlePromise(p, $resolved, x); | ||
} | ||
settleXthen(p, x, xthen); | ||
} else { | ||
settlePromise(p, $resolved, x); | ||
} | ||
return p; | ||
}; | ||
} else { | ||
settlePromise(p, $resolved, x); | ||
} | ||
return p; | ||
}; | ||
/** | ||
* Try to get a promise's then method. | ||
* @private | ||
* @param {Thenable} x | ||
* @return {Function} | ||
*/ | ||
/** | ||
* Try to get a promise's then method. | ||
* @private | ||
* @param {Thenable} x | ||
* @return {Function} | ||
*/ | ||
getThen = function(x) { | ||
return x.then; | ||
}; | ||
getThen = function(x) { | ||
return x.then; | ||
}; | ||
/** | ||
* Resolve then with its promise. | ||
* @private | ||
* @param {Yaku} p | ||
* @param {Thenable} x | ||
* @param {Function} xthen | ||
*/ | ||
/** | ||
* Resolve then with its promise. | ||
* @private | ||
* @param {Yaku} p | ||
* @param {Thenable} x | ||
* @param {Function} xthen | ||
*/ | ||
settleXthen = function(p, x, xthen) { | ||
var err; | ||
err = genTryCatcher(xthen).call(x, function(y) { | ||
if (!x) { | ||
return; | ||
} | ||
x = null; | ||
settleWithX(p, y); | ||
}, function(r) { | ||
if (!x) { | ||
return; | ||
} | ||
x = null; | ||
settlePromise(p, $rejected, r); | ||
}); | ||
if (err === $tryErr && x) { | ||
settlePromise(p, $rejected, err.e); | ||
x = null; | ||
settleXthen = function(p, x, xthen) { | ||
var err; | ||
err = genTryCatcher(xthen).call(x, function(y) { | ||
if (!x) { | ||
return; | ||
} | ||
}; | ||
x = null; | ||
settleWithX(p, y); | ||
}, function(r) { | ||
if (!x) { | ||
return; | ||
} | ||
x = null; | ||
settlePromise(p, $rejected, r); | ||
}); | ||
if (err === $tryErr && x) { | ||
settlePromise(p, $rejected, err.e); | ||
x = null; | ||
} | ||
}; | ||
try { | ||
module.exports = Yaku; | ||
} catch (_error) { | ||
try { | ||
module.exports = Yaku; | ||
define(function() { | ||
return Yaku; | ||
}); | ||
} catch (_error) { | ||
try { | ||
define(function() { | ||
return Yaku; | ||
}); | ||
} catch (_error) { | ||
root.Yaku = Yaku; | ||
} | ||
root.Yaku = Yaku; | ||
} | ||
} | ||
return Yaku; | ||
return Yaku; | ||
})(); | ||
})(); |
{ | ||
"name": "yaku", | ||
"version": "0.3.1", | ||
"version": "0.3.2", | ||
"description": "An ES6 Promise/A+ implementation that doesn't hurt.", | ||
@@ -31,7 +31,7 @@ "main": "lib/yaku.js", | ||
"devDependencies": { | ||
"bluebird": "2.9.33", | ||
"bluebird": "2.9.34", | ||
"coffee-script": "1.9.3", | ||
"coffeelint": "1.10.1", | ||
"es6-promise": "2.3.0", | ||
"nokit": "0.9.1", | ||
"nokit": "0.9.2", | ||
"promises-aplus-tests": "*", | ||
@@ -38,0 +38,0 @@ "q": "1.4.1", |
@@ -9,3 +9,3 @@ <a href="http://promisesaplus.com/"> | ||
Yaku is full compatible with ES6's native [Promise][native], but much faster, and more error friendly. | ||
If you want to learn how Promise works, read the minimum implementation [docs/minPromiseA+.coffee][]. Without comments, it is only 80 lines of code. | ||
If you want to learn how Promise works, read the minimum implementation [docs/minPromiseA+.coffee][]. Without comments, it is only 80 lines of code (minified size is 1.2KB). | ||
It only implements the `constructor` and `then`. It passed all the tests of [promises-aplus-tests][]. | ||
@@ -21,3 +21,3 @@ | ||
- The minified file is only 3.6KB ([Bluebird][] / 73KB, [ES6-promise][] / 18KB) | ||
- The minified file is only 3.5KB ([Bluebird][] / 73KB, [ES6-promise][] / 18KB) | ||
- 100% compliant with Promise/A+ specs | ||
@@ -58,5 +58,6 @@ - Better performance than the native Promise | ||
These comparisons only reflect some limited truth, no one is better than all others on all aspects. | ||
For more details see the [benchmark/readme.md](benchmark/readme.md) | ||
``` | ||
iojs v1.8.1 | ||
iojs v1.8.4 | ||
OS darwin | ||
@@ -67,9 +68,9 @@ Arch x64 | ||
| Name | Unit Test | 1ms async task | sync task | Helpers | file size | | ||
| -------------------- | --------- | -------------- | --------- | ------- | --------- | | ||
| Yaku | 872/872 | 283ms | 68ms | ++ | 3.6KB | | ||
| [Bluebird][] v2.9 | 872/872 | 272ms | 164ms | +++++++ | 73KB | | ||
| [ES6-promise][] v2.1 | 872/872 | 459ms | 110ms | + | 18KB | | ||
| [native][] iojs v1.8 | 872/872 | 826ms | 605ms | + | 0KB | | ||
| [q][] v1.3 | 208/872 | 2710ms | 2327ms | +++ | 24K | | ||
| Name | 1ms async task / mem | sync task / mem | Helpers | file size | | ||
| -------------------- | -------------------- | --------------- | ------- | --------- | | ||
| Yaku | 257ms / 110MB | 126ms / 80MB | +++ | 3.5KB | | ||
| [Bluebird][] v2.9 | 249ms / 102MB | 155ms / 80MB | +++++++ | 73KB | | ||
| [ES6-promise][] v2.3 | 427ms / 120MB | 92ms / 78MB | + | 18KB | | ||
| [native][] iojs v1.8 | 789ms / 189MB | 605ms / 147MB | + | 0KB | | ||
| [q][] v1.3 | 2648ms / 646MB | 2373ms / 580MB | +++ | 24K | | ||
@@ -108,3 +109,3 @@ - **Helpers**: extra methods that help with your promise programming, such as | ||
- ### **[constructor(executor)](src/yaku.coffee?source#L31)** | ||
- ### **[constructor(executor)](src/yaku.coffee?source#L40)** | ||
@@ -117,5 +118,8 @@ This class follows the [Promises/A+](https://promisesaplus.com) and | ||
Function object with two arguments resolve and reject. | ||
Function object with three arguments resolve, reject and | ||
the promise itself. | ||
The first argument fulfills the promise, the second argument rejects it. | ||
We can call these functions, once our operation is completed. | ||
The third argument can be used to add custom handlers, such as `abort` or `progress` | ||
helpers. | ||
@@ -126,4 +130,8 @@ - **<u>example</u>**: | ||
Promise = require 'yaku' | ||
p = new Promise (resolve, reject) -> | ||
setTimeout -> | ||
p = new Promise (resolve, reject, self) -> | ||
self.abort = -> | ||
clearTimeout tmr | ||
reject new Error 'abort promise' | ||
tmr = setTimeout -> | ||
if Math.random() > 0.5 | ||
@@ -133,5 +141,7 @@ resolve 'ok' | ||
reject 'no' | ||
, 3000 | ||
p.abort() | ||
``` | ||
- ### **[then(onFulfilled, onRejected)](src/yaku.coffee?source#L61)** | ||
- ### **[then(onFulfilled, onRejected)](src/yaku.coffee?source#L73)** | ||
@@ -164,3 +174,3 @@ Appends fulfillment and rejection handlers to the promise, | ||
- ### **[catch(onRejected)](src/yaku.coffee?source#L79)** | ||
- ### **[catch(onRejected)](src/yaku.coffee?source#L91)** | ||
@@ -189,3 +199,3 @@ The `catch()` method returns a Promise and deals with rejected cases only. | ||
- ### **[@resolve(value)](src/yaku.coffee?source#L95)** | ||
- ### **[@resolve(value)](src/yaku.coffee?source#L107)** | ||
@@ -210,3 +220,3 @@ The `Promise.resolve(value)` method returns a Promise object that is resolved with the given value. | ||
- ### **[@reject(reason)](src/yaku.coffee?source#L109)** | ||
- ### **[@reject(reason)](src/yaku.coffee?source#L121)** | ||
@@ -228,3 +238,3 @@ The `Promise.reject(reason)` method returns a Promise object that is rejected with the given reason. | ||
- ### **[@race(iterable)](src/yaku.coffee?source#L131)** | ||
- ### **[@race(iterable)](src/yaku.coffee?source#L143)** | ||
@@ -257,3 +267,3 @@ The `Promise.race(iterable)` method returns a promise that resolves or rejects | ||
- ### **[@all(iterable)](src/yaku.coffee?source#L168)** | ||
- ### **[@all(iterable)](src/yaku.coffee?source#L180)** | ||
@@ -287,3 +297,3 @@ The `Promise.all(iterable)` method returns a promise that resolves when | ||
- ### **[@onUnhandledRejection(reason)](src/yaku.coffee?source#L218)** | ||
- ### **[@onUnhandledRejection(reason)](src/yaku.coffee?source#L230)** | ||
@@ -312,3 +322,3 @@ Catch all possibly unhandled rejections. If you want to use specific | ||
- ### **[@enableLongStackTrace](src/yaku.coffee?source#L238)** | ||
- ### **[@enableLongStackTrace](src/yaku.coffee?source#L250)** | ||
@@ -328,3 +338,3 @@ It is used to enable the long stack trace. | ||
- ### **[@nextTick](src/yaku.coffee?source#L255)** | ||
- ### **[@nextTick](src/yaku.coffee?source#L267)** | ||
@@ -353,3 +363,3 @@ Only Node has `process.nextTick` function. For browser there are | ||
- ### **[async(limit, list, saveResults, progress)](src/utils.coffee?source#L68)** | ||
- ### **[async(limit, list, saveResults, progress)](src/utils.coffee?source#L65)** | ||
@@ -420,3 +430,3 @@ An throttled version of `Promise.all`, it runs all the tasks under | ||
- ### **[callbackify(fn, self)](src/utils.coffee?source#L144)** | ||
- ### **[callbackify(fn, self)](src/utils.coffee?source#L147)** | ||
@@ -434,11 +444,11 @@ If a function returns promise, convert it to | ||
- ### **[Deferred](src/utils.coffee?source#L166)** | ||
- ### **[Deferred](src/utils.coffee?source#L169)** | ||
Create a `jQuery.Deferred` like object. | ||
- ### **[end](src/utils.coffee?source#L178)** | ||
- ### **[end](src/utils.coffee?source#L181)** | ||
The end symbol. | ||
- ### **[flow(fns)](src/utils.coffee?source#L233)** | ||
- ### **[flow(fns)](src/utils.coffee?source#L236)** | ||
@@ -445,0 +455,0 @@ Creates a function that is the composition of the provided functions. |
598
48807
1024