Source: modules/promise.js

/**
 * Module for polyfilling promises
 */
(function(w, undefined) {

	if (typeof Promise === "undefined")
	{
		/**
		 * Promise constructor
		 *
		 * @constructor
		 * @namespace
		 * @param function fn
		 */
		w.Promise = function(fn)
		{
			var state = 'pending';
			var value;
			var deferred = null;

			function resolve(newValue)
			{
				try
				{
					if (newValue && typeof newValue.then === 'function')
					{
						newValue.then(resolve);
						return;
					}

					state = 'resolved';
					value = newValue;

					if (deferred)
					{
						handle(deferred);
					}
				}
				catch(e)
				{
					reject(e);
				}
			}

			function reject(reason)
			{
				state = 'rejected';
				value = reason;

				if (deferred)
				{
					handle(deferred);
				}

			}

			function handle(handler)
			{
				if (state === 'pending')
				{
					deferred = onResolved;
					return;
				}

				var handlerCallback;

				setTimeout(function() {
					handlerCallback = (state === 'resolved')
						? handler.onResolved
						: handler.onRejected;


					if ( ! handlerCallback)
					{

						(state === 'resolved')
							? handler.resolve(value)
							: handler.reject(value);

						return;
					}

					try
					{
						ret = handlerCallback(value);
					}
					catch(e)
					{
						handler.reject(e);
						return;
					}

					handler.resolve(ret);
				}, 1);
			}

			this.then = function(onResolved, onRejected) {
				return new Promise(function(resolve, reject) {
					handle({
						onResolved: onResolved,
						onRejected: onRejected,
						resolve: resolve,
						reject: reject
					});
				});
			};

			fn(resolve, reject);
		}
	}

})(window);