function fooPromise() {
    var deferred = $.Deferred();

    setTimeout(function() {
        deferred.resolve("foo");
    }, 1000);

    return deferred.promise();
}
fooPromise().then(
    function(value) {
        // prints "foo" after 1 second
        console.log(value);
    },
    function() { console.log("something went wrong"); }
);
function getPost(id) {
    return $.getJSON('/posts/'+ id);
}

function getUser(id) {
    return $.getJSON('/users/'+ id);
}
function authorForPost(id) {
    var postPromise = getPost(id),
        deferred = $.Deferred();

    postPromise.then(function(post) {
        var authorPromise = getUser(post.authorId);

        authorPromise.then(function(author) {
            deferred.resolve(author);
        });
    });

    return deferred.promise();
}
function authorForPost(id) {
    var postPromise = getPost(id),
        deferred = $.Deferred();

    postPromise.then(function(post) {
        return getUser(post.authorId);
    }).then(function(author) {
        deferred.resolve(author);
    });

    return deferred.promise();
}
function postWithAuthor(id) {
    return getPost(id).then(function(post) {
        var userId = post.authorId;
        return getUser(userId).then(function(author) {
            return $.extend(post, { author: author });
        });
    });
}
function getTwoUsers(idA, idB) {
    var userPromiseA = getUser(idA),
        userPromiseB = getUser(idB);

    return $.when(userPromiseA, userPromiseB);
}

getTwoUsers(1002, 1008).then(function(userA, userB) {
    $(render(userA)).appendTo('#users');
    $(render(userB)).appendTo('#users');
});
customizable avatar
var myAvatar = {
    name:       '[enter name here]',
    height:     170,
    hatStyle:   'conductor/skater',
    shirtColor: 'rgb(12, 12, 250)'
};

function update() {
    drawAvatar({
        name:       myAvatar.name,
        height:     myAvatar.height,
        hatStyle:   myAvatar.hatStyle,
        shirtColor: myAvatar.shirtColor
    });
}
function getShirtColor() {
    openColorPicker().then(function(color) {
        myAvatar.shirtColor = color;
        update();
    });
}
function getShirtColor() {
    openColorPicker().then(function(color) {

        myAvatar.shirtColor = color;

        save(myAvatar).then(function(savedAvatar) {
            myAvatar = savedAvatar;
            update();
        });

    });
}
var deferred = $.Deferred();

deferred.resolve({
    name:       '[enter name here]',
    height:     170,
    hatStyle:   'conductor/skater',
    shirtColor: 'rgb(12, 12, 250)'
});

var myAvatar = deferred.promise();
function getShirtColor() {
    myAvatar = $.when(openColorPicker(), myAvatar)
    .then(function(color, avatar) {

        var updatedAvatar = $.extend({}, avatar, {
            shirtColor: color
        });

        return save(updatedAvatar);

    });
}
function orElse(promise, fallback) {
    var d = $.Deferred();

    promise.then(
        d.resolve,
        function() {
            fallback.then(d.resolve, d.reject);
        }
    );

    return d.promise();
}
function getShirtColor() {
    var withChange = $.when(openColorPicker(), myAvatar)
    .then(function(color, avatar) {

        var updatedAvatar = $.extend({}, avatar, {
            shirtColor: color
        });

        return save(updatedAvatar);

    });

    myAvatar = orElse(withChange, myAvatar);
}
function getShirtColor() {
    var withChange = myAvatar.then(function(avatar) {
        openColorPicker(avatar.shirtColor).then(function(color) {

            var updatedAvatar = $.extend({}, avatar, {
                shirtColor: color
            });

            return save(updatedAvatar);

        });
    });

    myAvatar = orElse(withChange, myAvatar);
}

sitr.us/talks/monadic-promises/

sitr.us/2012/07/31/promise-pipelines-in-javascript.html

wiki.commonjs.org/wiki/Promises/A