From 4fce3c5fdb8a61255a7f4ff2f58d369f7e8f9196 Mon Sep 17 00:00:00 2001 From: Ben Lau Date: Sat, 23 May 2015 01:35:46 +0800 Subject: [PATCH] Let Q.promise() support signal object as argument to resolve() / reject() --- QuickPromise/Promise.qml | 22 ++-------------------- QuickPromise/q.js | 26 +++++++++++++++++++++++++- README.md | 15 +++++++++++++++ 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/QuickPromise/Promise.qml b/QuickPromise/Promise.qml index 6534240..eb50604 100644 --- a/QuickPromise/Promise.qml +++ b/QuickPromise/Promise.qml @@ -44,27 +44,13 @@ QtObject { function resolve(value) { if (instanceOfPromise(value)) { value = value._promise; - } else if (_instanceOfSignal(value)) { - var promise = Q.promise(); - value.connect(function() { - promise.resolve(); - }); - value = promise; } _promise.resolve(value); } function reject(reason) { - if (_instanceOfSignal(reason)) { - var promise = Q.promise(); - reason.connect(function() { - promise.reject(); - }); - _promise.resolve(promise); - } else { - _promise.reject(reason); - } + _promise.reject(reason); } /// Combine multiple promises into a single promise. @@ -82,11 +68,7 @@ QtObject { } function _instanceOfSignal(object) { - return (typeof object === "object" || - typeof object === "function") && - typeof object.hasOwnProperty === "function" && - typeof object.connect === "function" && - typeof object.disconnect === "function"; + return Q._instanceOfSignal(object); } function _init() { diff --git a/QuickPromise/q.js b/QuickPromise/q.js index 9481ffc..9fc8460 100644 --- a/QuickPromise/q.js +++ b/QuickPromise/q.js @@ -34,6 +34,14 @@ function instanceOfPromise(object) { return object.hasOwnProperty("___promiseSignature___"); } +function _instanceOfSignal(object) { + return (typeof object === "object" || + typeof object === "function") && + typeof object.hasOwnProperty === "function" && + typeof object.connect === "function" && + typeof object.disconnect === "function"; +} + Promise.prototype.then = function(onFulfilled,onRejected) { var thenPromise = new Promise(); @@ -84,6 +92,15 @@ Promise.prototype.resolve = function(value) { } var promise = this; + + if (value && _instanceOfSignal(value)) { + // resolve(signal) + var newPromise = new Promise(); + value.connect(function() { + newPromise.resolve(); + }); + value = newPromise; + } if (value && instanceOfPromise(value)) { @@ -104,7 +121,7 @@ Promise.prototype.resolve = function(value) { return; } } - + if (value !== null && (typeof value === "object" || typeof value === "function")) { var then; try { @@ -174,6 +191,13 @@ Promise.prototype.reject = function(reason) { var promise = this; + if (reason && _instanceOfSignal(reason)) { + reason.connect(function() { + promise.reject(); + }); + return; + } + QP.QPTimer.setTimeout(function() { if (promise.state !== "pending") return; diff --git a/README.md b/README.md index 5389ba6..f49e5be 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,16 @@ Promise { } ``` +**isFullfilled** +It is true if resolve() has been called on that promise object + +**isRejected** +It is true if reject() has been called on that promise object + +**isSettled** +It is true if either of isFullfilled or isRejected has been set. + + **resolveWhen** resolveWhen property is an alternative method to call resolve() in QML way. You may bind a binary expression, another promise, signal to the "resolveWhen" property. It may trigger the resolve() depend on its type and value. @@ -192,6 +202,10 @@ Q.promise() Q.promise() is the creator function of Promise object in Javascript way. You won't need to declare a QML component before use it. As it is fully compliant with Promise/A+ specification, it is very easy to get started. However, it don't support property binding (resolveWhen , rejectWhen) and signal (fulfilled, rejected , settled) like the Promise QML component. +However, you may pass a signal object to resolve()/reject(). In this case, the promise will not change its state until the signal is triggered. If multiple signal call are made, the first signal call takes precedence, and any further calls are ignored. + +*API* + ``` Promise.prototype.then = function(onFulfilled,onRejected) { ... } Promise.prototype.resolve = function(value) { ... } @@ -200,6 +214,7 @@ Promise.prototype.reject = function(reason) { ... } Instruction of using then/resolve/reject: [Promises](https://www.promisejs.org/) + Extra API ---------