jQuery .then() and error propagation

by Himanshu Joshi

HTML

<div>
    <p>This is a simple example of how jQuery forwarding works in promise resolutions and rejections.</p>
    <p>This example is forked from <a href="http://jsfiddle.net/briancavalier/4canN/">Brian Cavalier's example</a> of when.js promise forwarding.</p>
</div>

JavaScript

var dfd;

dfd = $.Deferred();

// Resolved promises chain and forward values to next promise
// The first promise, d.promise, will resolve with the value passed
// to d.resolve() below.
// Each call to .then() returns a new promise that will resolve
// with the return value of the previous handler.  This creates a
// promise "pipeline".
dfd
    .then(function(x) {
        // x will be the value passed to d.reject() below
        // and returns a *new promise* for x + 1
        return x + 1;
    })
    .then(function(x) {
        // x === 2
        // This handler receives the return value of the
        // previous handler.
        return x + 1;
    })
    .then(function(x) {
        // x === 3
        // This handler receives the return value of the
        // previous handler.
        return x + 1;
    })
    .then(function(x) {
        // x === 4
        // This handler receives the return value of the
        // previous handler.
        log('resolve ' + x);
    });

dfd.resolve(1);

// Thrown errors are not propogated by .then()
dfd = $.Deferred();

dfd
    .then(null, function(x) {
        return x + 1; // 2
    })
    .then(null, function(x) {
        return x + 1; // 3
    })
    .then(null, function(x) {
        log('reject ' + x); // 3
        return x + 1; // 4
    })
    .then(null, function(x) {
        
       // you can throw an error but you have to catch it 
       // otherwise execution will be halted.
       try {
            throw new Error('Error');
        }
        catch (e) {
            log(e);
        };
        
        return x + 1; // 5
    })
    .then(null, function(x) {
        log(x); // 5
    });
dfd.reject(1);

// Thrown errors are not propogated by .then()
dfd = $.Deferred();


dfd
    .then(null, function(x) {
        
        // propogate rejected value and modify it
        return x + 1; // 2
    })
    .then(null, function(x) {
        return x + 1; // 3
    })
    .then(null, function(x) {
        return x + 1; // 4
   ...