Promise Scenarios with jQuery (Monkey Patched)

by jdiamond

HTML

<p>Open your console. There should be no uncaught errors.</p>

JavaScript

function getValue() {
  return $.Deferred(function(d) {
    setTimeout(function() {
      d.resolve('ok');
    }, 100);
  }).promise();
}

function getError() {
  return $.Deferred(function(d) {
    setTimeout(function() {
      d.reject('error');
    }, 100);
  }).promise();
}

$.Deferred = (function() {
  var oldDeferred = $.Deferred;

  return function Deferred(fn) {
	  var d = oldDeferred(fn);
	  var oldThen = d.then;
	  d.then = d.promise().then = function(done, fail, progress) {
  	  return oldThen.call(d, wrap(done), wrap(fail), wrap(progress));
  	};
  	return d;
	};

  function wrap(fn) {
    return fn && function() {
      try {
        var val = fn.apply(this, arguments);
        return (val && val.promise) ? val :
        $.Deferred(function(d) {
          d.resolve(val);
        }).promise();
      } catch (err) {
        return $.Deferred(function(d) {
          d.reject(err);
        }).promise();
      }
    }
  }
})();

// 1. Fulfilled, fulfillment handler returns a value: simple functional transformation

getValue()
.then(function(val) {
  return val;
})
.then(
  function(val) {
    console.log(val);
  },
  function(err) {
    console.log(err.message);
  }
);

// 2. Fulfilled, fulfillment handler throws an exception: getting data, and throwing an exception in response to it

getValue()
.then(function(val) {
  throw new Error('fulfillment handler error');
})
.then(
  function(val) {
    console.log(val);
  },
  function(err) {
    console.log(err.message);
  }
);

// 3. Rejected, rejection handler returns a value: a catch clause got the error and handled it

getError()
.then(null, function(err) {
  return 'fixed';
})
.then(
  function(val) {
    console.log(val);
  },
  function(err) {
    console.log(err.message);
  }
);

// 4. Rejected, rejection handler throws an exception: a catch clause got the error and re-threw it (or a new one)

getError()
.then(null, function(err) {
  throw new Error('rejection handler error');
})
.then(
  function(val)...