Moved
This commit is contained in:
279
CM2010 Software Design and Development/Topic 2/8.2.4/node_modules/workerpool/src/Promise.js
generated
vendored
Normal file
279
CM2010 Software Design and Development/Topic 2/8.2.4/node_modules/workerpool/src/Promise.js
generated
vendored
Normal file
@ -0,0 +1,279 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Promise
|
||||
*
|
||||
* Inspired by https://gist.github.com/RubaXa/8501359 from RubaXa <trash@rubaxa.org>
|
||||
*
|
||||
* @param {Function} handler Called as handler(resolve: Function, reject: Function)
|
||||
* @param {Promise} [parent] Parent promise for propagation of cancel and timeout
|
||||
*/
|
||||
function Promise(handler, parent) {
|
||||
var me = this;
|
||||
|
||||
if (!(this instanceof Promise)) {
|
||||
throw new SyntaxError('Constructor must be called with the new operator');
|
||||
}
|
||||
|
||||
if (typeof handler !== 'function') {
|
||||
throw new SyntaxError('Function parameter handler(resolve, reject) missing');
|
||||
}
|
||||
|
||||
var _onSuccess = [];
|
||||
var _onFail = [];
|
||||
|
||||
// status
|
||||
this.resolved = false;
|
||||
this.rejected = false;
|
||||
this.pending = true;
|
||||
|
||||
/**
|
||||
* Process onSuccess and onFail callbacks: add them to the queue.
|
||||
* Once the promise is resolve, the function _promise is replace.
|
||||
* @param {Function} onSuccess
|
||||
* @param {Function} onFail
|
||||
* @private
|
||||
*/
|
||||
var _process = function (onSuccess, onFail) {
|
||||
_onSuccess.push(onSuccess);
|
||||
_onFail.push(onFail);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add an onSuccess callback and optionally an onFail callback to the Promise
|
||||
* @param {Function} onSuccess
|
||||
* @param {Function} [onFail]
|
||||
* @returns {Promise} promise
|
||||
*/
|
||||
this.then = function (onSuccess, onFail) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var s = onSuccess ? _then(onSuccess, resolve, reject) : resolve;
|
||||
var f = onFail ? _then(onFail, resolve, reject) : reject;
|
||||
|
||||
_process(s, f);
|
||||
}, me);
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolve the promise
|
||||
* @param {*} result
|
||||
* @type {Function}
|
||||
*/
|
||||
var _resolve = function (result) {
|
||||
// update status
|
||||
me.resolved = true;
|
||||
me.rejected = false;
|
||||
me.pending = false;
|
||||
|
||||
_onSuccess.forEach(function (fn) {
|
||||
fn(result);
|
||||
});
|
||||
|
||||
_process = function (onSuccess, onFail) {
|
||||
onSuccess(result);
|
||||
};
|
||||
|
||||
_resolve = _reject = function () { };
|
||||
|
||||
return me;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reject the promise
|
||||
* @param {Error} error
|
||||
* @type {Function}
|
||||
*/
|
||||
var _reject = function (error) {
|
||||
// update status
|
||||
me.resolved = false;
|
||||
me.rejected = true;
|
||||
me.pending = false;
|
||||
|
||||
_onFail.forEach(function (fn) {
|
||||
fn(error);
|
||||
});
|
||||
|
||||
_process = function (onSuccess, onFail) {
|
||||
onFail(error);
|
||||
};
|
||||
|
||||
_resolve = _reject = function () { }
|
||||
|
||||
return me;
|
||||
};
|
||||
|
||||
/**
|
||||
* Cancel te promise. This will reject the promise with a CancellationError
|
||||
* @returns {Promise} self
|
||||
*/
|
||||
this.cancel = function () {
|
||||
if (parent) {
|
||||
parent.cancel();
|
||||
}
|
||||
else {
|
||||
_reject(new CancellationError());
|
||||
}
|
||||
|
||||
return me;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set a timeout for the promise. If the promise is not resolved within
|
||||
* the time, the promise will be cancelled and a TimeoutError is thrown.
|
||||
* If the promise is resolved in time, the timeout is removed.
|
||||
* @param {number} delay Delay in milliseconds
|
||||
* @returns {Promise} self
|
||||
*/
|
||||
this.timeout = function (delay) {
|
||||
if (parent) {
|
||||
parent.timeout(delay);
|
||||
}
|
||||
else {
|
||||
var timer = setTimeout(function () {
|
||||
_reject(new TimeoutError('Promise timed out after ' + delay + ' ms'));
|
||||
}, delay);
|
||||
|
||||
me.always(function () {
|
||||
clearTimeout(timer);
|
||||
});
|
||||
}
|
||||
|
||||
return me;
|
||||
};
|
||||
|
||||
// attach handler passing the resolve and reject functions
|
||||
handler(function (result) {
|
||||
_resolve(result);
|
||||
}, function (error) {
|
||||
_reject(error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute given callback, then call resolve/reject based on the returned result
|
||||
* @param {Function} callback
|
||||
* @param {Function} resolve
|
||||
* @param {Function} reject
|
||||
* @returns {Function}
|
||||
* @private
|
||||
*/
|
||||
function _then(callback, resolve, reject) {
|
||||
return function (result) {
|
||||
try {
|
||||
var res = callback(result);
|
||||
if (res && typeof res.then === 'function' && typeof res['catch'] === 'function') {
|
||||
// method returned a promise
|
||||
res.then(resolve, reject);
|
||||
}
|
||||
else {
|
||||
resolve(res);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an onFail callback to the Promise
|
||||
* @param {Function} onFail
|
||||
* @returns {Promise} promise
|
||||
*/
|
||||
Promise.prototype['catch'] = function (onFail) {
|
||||
return this.then(null, onFail);
|
||||
};
|
||||
|
||||
// TODO: add support for Promise.catch(Error, callback)
|
||||
// TODO: add support for Promise.catch(Error, Error, callback)
|
||||
|
||||
/**
|
||||
* Execute given callback when the promise either resolves or rejects.
|
||||
* @param {Function} fn
|
||||
* @returns {Promise} promise
|
||||
*/
|
||||
Promise.prototype.always = function (fn) {
|
||||
return this.then(fn, fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a promise which resolves when all provided promises are resolved,
|
||||
* and fails when any of the promises resolves.
|
||||
* @param {Promise[]} promises
|
||||
* @returns {Promise} promise
|
||||
*/
|
||||
Promise.all = function (promises){
|
||||
return new Promise(function (resolve, reject) {
|
||||
var remaining = promises.length,
|
||||
results = [];
|
||||
|
||||
if (remaining) {
|
||||
promises.forEach(function (p, i) {
|
||||
p.then(function (result) {
|
||||
results[i] = result;
|
||||
remaining--;
|
||||
if (remaining == 0) {
|
||||
resolve(results);
|
||||
}
|
||||
}, function (error) {
|
||||
remaining = 0;
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
resolve(results);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a promise resolver
|
||||
* @returns {{promise: Promise, resolve: Function, reject: Function}} resolver
|
||||
*/
|
||||
Promise.defer = function () {
|
||||
var resolver = {};
|
||||
|
||||
resolver.promise = new Promise(function (resolve, reject) {
|
||||
resolver.resolve = resolve;
|
||||
resolver.reject = reject;
|
||||
});
|
||||
|
||||
return resolver;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a cancellation error
|
||||
* @param {String} [message]
|
||||
* @extends Error
|
||||
*/
|
||||
function CancellationError(message) {
|
||||
this.message = message || 'promise cancelled';
|
||||
this.stack = (new Error()).stack;
|
||||
}
|
||||
|
||||
CancellationError.prototype = new Error();
|
||||
CancellationError.prototype.constructor = Error;
|
||||
CancellationError.prototype.name = 'CancellationError';
|
||||
|
||||
Promise.CancellationError = CancellationError;
|
||||
|
||||
|
||||
/**
|
||||
* Create a timeout error
|
||||
* @param {String} [message]
|
||||
* @extends Error
|
||||
*/
|
||||
function TimeoutError(message) {
|
||||
this.message = message || 'timeout exceeded';
|
||||
this.stack = (new Error()).stack;
|
||||
}
|
||||
|
||||
TimeoutError.prototype = new Error();
|
||||
TimeoutError.prototype.constructor = Error;
|
||||
TimeoutError.prototype.name = 'TimeoutError';
|
||||
|
||||
Promise.TimeoutError = TimeoutError;
|
||||
|
||||
|
||||
module.exports = Promise;
|
||||
Reference in New Issue
Block a user