--- layout: deckjs-pygments title: "Promises and monadic concurrency" description: "pdxjs presentation 2013-02-27" author: "Jesse Hallett" ---
{%highlight js %} function fooPromise() { var deferred = $.Deferred(); setTimeout(function() { deferred.resolve("foo"); }, 1000); return deferred.promise(); } {% endhighlight %}
{%highlight js %} fooPromise().then( function(value) { // prints "foo" after 1 second console.log(value); }, function() { console.log("something went wrong"); } ); {% endhighlight %}
{%highlight js %} function getPost(id) { return $.getJSON('/posts/'+ id); } function getUser(id) { return $.getJSON('/users/'+ id); } {% endhighlight %}
{%highlight js %} 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(); } {% endhighlight %}
{%highlight js %} 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(); } {% endhighlight %}
{%highlight js %} function postWithAuthor(id) { return getPost(id).then(function(post) { var userId = post.authorId; return getUser(userId).then(function(author) { return $.extend(post, { author: author }); }); }); } {% endhighlight %}
{%highlight js %} 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'); }); {% endhighlight %}
customizable avatar
{%highlight js %} 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 }); } {% endhighlight %}
{%highlight js %} function getShirtColor() { openColorPicker().then(function(color) { myAvatar.shirtColor = color; update(); }); } {% endhighlight %}
{%highlight js %} function getShirtColor() { openColorPicker().then(function(color) { myAvatar.shirtColor = color; save(myAvatar).then(function(savedAvatar) { myAvatar = savedAvatar; update(); }); }); } {% endhighlight %}
{%highlight js %} var deferred = $.Deferred(); deferred.resolve({ name: '[enter name here]', height: 170, hatStyle: 'conductor/skater', shirtColor: 'rgb(12, 12, 250)' }); var myAvatar = deferred.promise(); {% endhighlight %}
{%highlight js %} function getShirtColor() { myAvatar = $.when(openColorPicker(), myAvatar) .then(function(color, avatar) { var updatedAvatar = $.extend({}, avatar, { shirtColor: color }); return save(updatedAvatar); }); } {% endhighlight %}
{%highlight js %} function orElse(promise, fallback) { var d = $.Deferred(); promise.then( d.resolve, function() { fallback.then(d.resolve, d.reject); } ); return d.promise(); } {% endhighlight %}
{%highlight js %} function getShirtColor() { var withChange = $.when(openColorPicker(), myAvatar) .then(function(color, avatar) { var updatedAvatar = $.extend({}, avatar, { shirtColor: color }); return save(updatedAvatar); }); myAvatar = orElse(withChange, myAvatar); } {% endhighlight %}
{%highlight js %} 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); } {% endhighlight %}

sitr.us/talks/monadic-promises/

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

wiki.commonjs.org/wiki/Promises/A