|
|
@@ -0,0 +1,126 @@
|
|
|
+
|
|
|
+// TODO: write comments and tests
|
|
|
+
|
|
|
+function Promise(executor) {
|
|
|
+ var deferred = $.Deferred();
|
|
|
+ var promise = deferred.promise();
|
|
|
+
|
|
|
+ if (typeof executor === 'function') {
|
|
|
+ executor(
|
|
|
+ function(value) { // resolve
|
|
|
+ if (Promise.immediate) {
|
|
|
+ promise._value = value;
|
|
|
+ }
|
|
|
+ deferred.resolve(value);
|
|
|
+ },
|
|
|
+ function() { // reject
|
|
|
+ deferred.reject();
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Promise.immediate) {
|
|
|
+ var origThen = promise.then;
|
|
|
+
|
|
|
+ promise.then = function(onFulfilled, onRejected) {
|
|
|
+ var state = promise.state();
|
|
|
+
|
|
|
+ if (state === 'resolved') {
|
|
|
+ if (typeof onFulfilled === 'function') {
|
|
|
+ return coercePromiseReturn(onFulfilled(promise._value), promise);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (state === 'rejected') {
|
|
|
+ if (typeof onRejected === 'function') {
|
|
|
+ return coercePromiseReturn(onRejected(), promise);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return origThen.call(promise, onFulfilled, onRejected);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return promise;
|
|
|
+}
|
|
|
+
|
|
|
+FC.Promise = Promise;
|
|
|
+
|
|
|
+Promise.immediate = true;
|
|
|
+
|
|
|
+
|
|
|
+Promise.resolve = function(value) {
|
|
|
+ if (value && typeof value.resolve === 'function') {
|
|
|
+ return value.promise();
|
|
|
+ }
|
|
|
+ if (value && typeof value.then === 'function') {
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ var deferred = $.Deferred().resolve(value);
|
|
|
+ var promise = deferred.promise();
|
|
|
+
|
|
|
+ if (Promise.immediate) {
|
|
|
+ var origThen = promise.then;
|
|
|
+
|
|
|
+ promise._value = value;
|
|
|
+
|
|
|
+ promise.then = function(onFulfilled, onRejected) {
|
|
|
+ if (typeof onFulfilled === 'function') {
|
|
|
+ return coercePromiseReturn(onFulfilled(value), promise);
|
|
|
+ }
|
|
|
+ return origThen.call(promise, onFulfilled, onRejected);
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ return promise;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+Promise.all = function(inputs) {
|
|
|
+ var hasAllValues = false;
|
|
|
+ var values;
|
|
|
+ var i, input;
|
|
|
+
|
|
|
+ if (Promise.immediate) {
|
|
|
+ hasAllValues = true;
|
|
|
+ values = [];
|
|
|
+
|
|
|
+ for (i = 0; i < inputs.length; i++) {
|
|
|
+ input = inputs[i];
|
|
|
+
|
|
|
+ if (input && typeof input.state === 'function' && input.state() === 'resolved' && ('_value' in input)) {
|
|
|
+ values.push(input._value);
|
|
|
+ }
|
|
|
+ else if (input && typeof input.then === 'function') {
|
|
|
+ hasAllValues = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ values.push(input);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (hasAllValues) {
|
|
|
+ return Promise.resolve(values);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return $.when.apply($.when, inputs).then(function() {
|
|
|
+ return $.when($.makeArray(arguments));
|
|
|
+ });
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+function coercePromiseReturn(returnValue, origPromise) {
|
|
|
+ if (returnValue && typeof returnValue.resolve === 'function') {
|
|
|
+ return returnValue.promise();
|
|
|
+ }
|
|
|
+ else if (returnValue && typeof returnValue.then === 'function') {
|
|
|
+ return returnValue;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return origPromise;
|
|
|
+ }
|
|
|
+}
|