summaryrefslogtreecommitdiff
path: root/js/src/Ice/Promise.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/Ice/Promise.js')
-rw-r--r--js/src/Ice/Promise.js295
1 files changed, 31 insertions, 264 deletions
diff --git a/js/src/Ice/Promise.js b/js/src/Ice/Promise.js
index ec61f0dcdef..464bbad5470 100644
--- a/js/src/Ice/Promise.js
+++ b/js/src/Ice/Promise.js
@@ -7,291 +7,58 @@
//
// **********************************************************************
-var Ice = require("../Ice/ModuleRegistry").Ice;
-Ice.__M.require(module,
- [
- "../Ice/Class",
- "../Ice/TimerUtil"
- ]);
+const Ice = require("../Ice/Timer").Ice;
+const Timer = Ice.Timer;
-var Timer = Ice.Timer;
-
-//
-// Promise State
-//
-var State = {Pending: 0, Success: 1, Failed: 2};
-
-var resolveImp = function(self, listener)
+class P extends Promise
{
- var callback = self.__state === State.Success ? listener.onResponse : listener.onException;
- try
+ constructor(cb)
{
- if(typeof callback !== "function")
- {
- listener.promise.setState(self.__state, self._args);
- }
- else
- {
- var result = callback.apply(null, self._args);
-
- //
- // Callback can return a new promise.
- //
- if(result && typeof result.then == "function")
+ let res, rej;
+ super((resolve, reject) =>
{
- result.then(
- function()
- {
- var args = arguments;
- listener.promise.succeed.apply(listener.promise, args);
- },
- function()
- {
- var args = arguments;
- listener.promise.fail.apply(listener.promise, args);
- });
- }
- else
- {
- listener.promise.succeed(result);
- }
- }
- }
- catch(e)
- {
- listener.promise.fail.call(listener.promise, e);
- }
-};
+ res = resolve;
+ rej = reject;
-var Promise = Ice.Class({
- __init__: function()
- {
- this.__state = State.Pending;
- this.__listeners = [];
- },
- then: function(onResponse, onException)
- {
- var promise = new Promise();
- var self = this;
- //
- // Use setImmediate so the listeners are not resolved until the call stack is empty.
- //
- Timer.setImmediate(
- function()
- {
- self.__listeners.push(
- {
- promise:promise,
- onResponse:onResponse,
- onException:onException
- });
- self.resolve();
- });
- return promise;
- },
- exception: function(onException)
- {
- return this.then(null, onException);
- },
- finally: function(cb)
- {
- var p = new Promise();
- var self = this;
-
- var finallyHandler = function(method)
- {
- return function()
- {
- var args = arguments;
- try
- {
- var result = cb.apply(null, args);
- if(result && typeof result.then == "function")
- {
- var handler = function(){ method.apply(p, args); };
- result.then(handler).exception(handler);
- }
- else
- {
- method.apply(p, args);
- }
- }
- catch(e)
+ if(cb !== undefined)
{
- method.apply(p, args);
+ cb(resolve, reject);
}
- };
- };
-
- Timer.setImmediate(
- function(){
- self.then(finallyHandler(p.succeed), finallyHandler(p.fail));
});
- return p;
- },
- delay: function(ms)
- {
- var p = new Promise();
-
- var self = this;
-
- var delayHandler = function(promise, method)
- {
- return function()
- {
- var args = arguments;
- Timer.setTimeout(
- function()
- {
- method.apply(promise, args);
- },
- ms);
- };
- };
-
- Timer.setImmediate(function()
- {
- self.then(delayHandler(p, p.succeed), delayHandler(p, p.fail));
- });
- return p;
- },
- resolve: function()
- {
- if(this.__state === State.Pending)
- {
- return;
- }
- var obj;
- while((obj = this.__listeners.pop()))
- {
- //
- // We use a separate function here to capture the listeners
- // in the loop.
- //
- resolveImp(this, obj);
- }
- },
- setState: function(state, args)
- {
- if(this.__state === State.Pending && state !== State.Pending)
- {
- this.__state = state;
- this._args = args;
- //
- // Use setImmediate so the listeners are not resolved until the call stack is empty.
- //
- var self = this;
- Timer.setImmediate(function(){ self.resolve(); });
- }
- },
- succeed: function()
- {
- var args = arguments;
- this.setState(State.Success, args);
- return this;
- },
- fail: function()
- {
- var args = arguments;
- this.setState(State.Failed, args);
- return this;
- },
- succeeded: function()
- {
- return this.__state === State.Success;
- },
- failed: function()
- {
- return this.__state === State.Failed;
- },
- completed: function()
- {
- return this.__state !== State.Pending;
+ this.resolve = res;
+ this.reject = rej;
}
-});
-
-//
-// Create a new promise object that is fulfilled when all the promise arguments
-// are fulfilled or is rejected when one of the promises is rejected.
-//
-Promise.all = function()
-{
- // If only one argument is provided, check if the argument is an array
- if(arguments.length === 1 && arguments[0] instanceof Array)
+
+ finally(cb)
{
- return Promise.all.apply(this, arguments[0]);
+ return this.then(
+ (value) => P.resolve(cb()).then(() => value),
+ (reason) => P.resolve(cb()).then(() => { throw reason; }));
}
- var promise = new Promise();
- var promises = Array.prototype.slice.call(arguments);
- var results = new Array(arguments.length);
-
- var pending = promises.length;
- if(pending === 0)
+ delay(ms)
{
- promise.succeed.apply(promise, results);
+ return this.then(
+ value => new P((resolve, reject) => Timer.setTimeout(() => resolve(value), ms)),
+ reason => new P((resolve, reject) => Timer.setTiemout(() => reject(reason), ms)));
}
- for(var i = 0; i < promises.length; ++i)
+
+ static get [Symbol.species]()
{
- //
- // Create an anonymous function to capture the loop index
- //
-
- /*jshint -W083 */
- (function(j)
- {
- if(promises[j] && typeof promises[j].then == "function")
- {
- promises[j].then(
- function()
- {
- results[j] = arguments;
- pending--;
- if(pending === 0)
- {
- promise.succeed.apply(promise, results);
- }
- },
- function()
- {
- promise.fail.apply(promise, arguments);
- });
- }
- else
- {
- results[j] = promises[j];
- pending--;
- if(pending === 0)
- {
- promise.succeed.apply(promise, results);
- }
- }
- }(i));
- /*jshint +W083 */
+ return P;
}
- return promise;
-};
-
-Promise.try = function(onResponse)
-{
- return new Promise().succeed().then(onResponse);
-};
-Promise.delay = function(ms)
-{
- if(arguments.length > 1)
+ static delay(ms, value)
{
- var p = new Promise();
- var args = Array.prototype.slice.call(arguments);
- ms = args.pop();
- return p.succeed.apply(p, args).delay(ms);
+ return new P(resolve => Timer.setTimeout(() => resolve(value), ms));
}
- else
+
+ static try(cb)
{
- return new Promise().succeed().delay(ms);
+ return P.resolve().then(cb);
}
-};
+}
-Ice.Promise = Promise;
+Ice.Promise = P;
module.exports.Ice = Ice;