Bladeren bron

add new promise lib

Adam Shaw 9 jaren geleden
bovenliggende
commit
75645d77fa
2 gewijzigde bestanden met toevoegingen van 127 en 0 verwijderingen
  1. 1 0
      src.json
  2. 126 0
      src/common/Promise.js

+ 1 - 0
src.json

@@ -6,6 +6,7 @@
     "moment-ext.js",
     "date-formatting.js",
     "common/Class.js",
+    "common/Promise.js",
     "common/EmitterMixin.js",
     "common/ListenerMixin.js",
     "common/MouseIgnorerMixin.js",

+ 126 - 0
src/common/Promise.js

@@ -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;
+	}
+}