Simple Deferred / Promise pattern in JavaScript I've wrote a very simple implementation of Deferred / Promise pattern (inspired by jQuery's $.deferred) for my tiny project (which does not use jQuery)

It can handle multiply onSuccess an onFail callbacks with result caching. Example in comments above the code.

/**
 * defer() returns methods:
 *      resolve(data) - request is successfully resolved (returns nothing)
 *      reject(msg) - request if failed (returns nothing)
 *      promise() - returns promise function
 *
 * promise() returns methods:
 *      done(successfulCallback) - add on successful callback (returns nothing)
 *      fail(failCallback) - add on fail callback (returns nothing)
 *
 * Example:
 *
 * function someHeavyRequest(url) {
 *      var d = defer();
 *      doHeavyRequest(url,
 *          function (data) {
 *              // on success
 *              // ...do something
 *              d.resolve(data);
 *          },
 *          function (data) {
 *              // on fail
 *              // ...do something
 *              d.reject(data);
 *          });
 *      return d.promise();
 * }
 *
 * var req = someHeavyRequest("http://some.url/of/request/");
 *
 * req.done(function (data) {
 *      console.log("We got it!");
 *      console.log(data);
 * });
 *
 * req.done(function (data) {
 *      console.log("We got it again without new request!");
 *      console.log(data);
 * });
 *
 * req.fail(function (data) {
 *      console.error("Something wrong");
 *      console.error(data);
 * });
 *
 */
function defer () {
    var status = 0, // 0 = in progress / 1 = successful / -1 = fail
        callbacks = { done: [], fail: [] },
        args = { resolve: [], reject: [] },
        execute = function (callbacks, args) {
            var f;
            while (callbacks.length) {
                f = callbacks.shift();
                if (f) f.apply(this, args);
            }
        };

    return {
        promise: function () {
            return {
                done: function (callback) {
                    callbacks.done.push(callback);
                    if (status === 1) {
                        execute(callbacks.done, args.resolve);
                    }
                },

                fail: function (callback) {
                    callbacks.fail.push(callback);
                    if (status === -1) {
                        execute(callbacks.fail,args.reject);
                    }
                }
            };
        },

        resolve: function () {
            status = 1;
            args.resolve = arguments;
            execute(callbacks.done, args.resolve);
        },

        reject: function () {
            status = -1;
            args.reject = arguments;
            execute(callbacks.fail, args.reject);
        }
    };
}
A few things caught my eye:


You can call resolve and later call reject too - or the other way around, or call either one multiple times. It should only allow the first resolve/reject call to have an effect.
status might as well be a string (pending, resolved, rejected) which obviate the need for a comment explaining the integer values, and would improve readability
The if(f) check in execute should probably be a full if(typeof f === 'function') check; lots of values are truthy without being functions. You could also do this check in done/fail and simply ignore/complain about non-function arguments.
There's some duplication between done/fail and resolve/reject.


For that last one, if the status becomes a string, it's also relative easy use that as a key for organizing the callbacks and arguments.

function defer() {
  var currentState = 'pending',
      callbacks    = { resolved: [], rejected: [] },
      args         = []; // only need 1 args array

  function execute(state) {
    var cb;
    while(callbacks[state].length) {
      cb = callbacks[state].shift();
      if( typeof cb === 'function' ) cb.apply(this, args);
    }
  }

  // generic function factory for done/fail functions
  function hook(state) {
    return function (cb) {
      callbacks[state].push(cb);
      if(currentState === state) execute(state);
    }
  }

  // generic function factory for resolve/reject functions
  function complete(state) {
    return function () {
      if(currentState !== 'pending') return; 
      args = Array.prototype.slice.call(arguments, 0);
      currentState = state;
      execute(state);
    }
  }

  return {
    promise: function () {
      return { done: hook('resolved'), fail: hook('rejected') };
    },
    resolve: complete('resolved'),
    reject:  complete('rejected')
  };
}


You may want to add then, always and isPending (or just state) functions. And once you've resolved or rejected, you might as well get rid of the callbacks you're not going to ever use (i.e. if resolved, clear out the reject-callbacks,and vice-versa).

Lastly, if you want to emulate jQuery, make it chainable, so you can call x.done(...).fail(...).fail(...).always(...) etc.