jQuery 1.5 - broken promises

A demonstration of how jQuery 1.5's promises don't hold to the Promises/A spec as outlined at http://wiki.commonjs.org/wiki/Promises/A

by brianarn

HTML

<p>According to the <a href="http://wiki.commonjs.org/wiki/Promises/A">Promises/A</a> spec, an implentation of a compatible promise will have a <code>.then</code> method. A quote from the specification:</p>
<blockquote>This function should return a new promise that is fulfilled when the given fulfilledHandler or errorHandler callback is finished. This allows promise operations to be chained together. The value returned from the callback handler is the fulfillment value for the returned promise</blockquote>
<p>Therefore, the chaining as shown in the JavaScript section should result in a series of different values being output to the list below.</p>
<ul id="output"></ul>
<p>It would appear that jQuery's implementation of the Promises/A spec is somewhat broken. :(</p>
<p>For a comparison: <a href="http://jsfiddle.net/brianarn/ccWP7/" target="_top">this fiddle's approach, using Dojo</a></p>

CSS

p {
    margin: 10px 0px;
}

blockquote {
    margin: 10px 20px;
}

#output {
    list-style: disc;
    margin-left: 16px;
}

JavaScript

// A simple utility function to generate output in a visible way
function addOutput(val, msg) {
    var li = document.createElement('li');
    msg = msg || 'Value received:';
    li.innerHTML = msg + ' ' + val;
    $('#output').append(li);
} // addOutput

$(document).ready(function() {
    // Post to the JSON echoing service.
    // Note that I'm explicitly *not* handling the response as JSON,
    // so that I simply get my string back.
    var def = $.ajax({
        type: 'POST',
        url: '/echo/json/',
        data: {
            json: '[1,2,"three"]'
        },
        success: function(val) {
            addOutput(val, 'Starting point:');
        }
    });

    // From here out, the code is identical for jQuery and Dojo.
    // Kind of neat, that. :)
    def.then(function(val) {
        // Should output the array
        addOutput(val);
        return true;
    }).then(function(val) {
        // Should output a true
        addOutput(val);
        return 3;
    }).then(function(val) {
        // Should output a 3
        addOutput(val);
        // No return
    }).then(function(val) {
        // Given that there was no return,
        // the received value is undefined,
        // as then returns a promise for the return value
        // of the callback, so should output 'undefined
        addOutput(val);
        return null;
    }).then(function(val) {
        // Should output null
        addOutput(val);
        return 4;
    }).then(function(val) {
        // Should output 4
        addOutput(val);
    });
});