Grégoire Charvet
greg@geekingfrog.com
Ajax: Asynchronous javascript and XML
With jquery in the browser
$("#loading-sign").hide(500, function elementHidden() {
$("#ok-sign").show(); // executed when the #loading-sign is hidden, after 500ms});
With node (node.js style callback)
require('fs').readdir('.', function(err, files){
if(err) {
console.error(err);
} else {
console.log("there are "+files.length+" objects in the current directory");
}
});
$.getJSON("/api/get_recent_news", function gotNews(news) {
console.log("got "+news.length+" news");
}, function rejected(xhr){
console.error("request failed because "+xhr.responseText);
});
Emit an event when the action is completed (or failed)
var server = require('http').createServer();
server.on('request', function onRequest(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Pong");
response.end();
}
server.listen(8080);
With jquery
var getNews = $.getJSON("/api/get_latest_news"); //ajax call
getNews.done(function gotNews(news){ //invoked when the server responds
console.log("There are "+news.length+" recent news");});
In node: Q module by Kriskowal.
var createPromise = function() {
var deferred = $.Deferred();
setTimeout(function resolver(){
deferred.resolve("Hello");
}, 1000);
return deferred.promise();
}
var promise = createPromise()
promise.done(function promiseResolved(message) {
console.log("got message: "+message);
});
console.log("all done");
Output ?
all done
// 1 second later
got message: Hello
setTimeout(function addCallback() {
console.log("adding a callback");
promise.done(function{ //promise is already resolved here
$("#ok").show();
console.log("show element");
});
console.log("callback added")
, 5000);
Output ?
adding a callback
show element
callback added
building a news feed
{
"user_id": "123",
"feeds_ids": [
2, 3, 5
]
}
$.getJSON("/api/feeds/2/latest")
Using the then method on a promise to return another value
promise.then(function transform(value){
//transform value here and return a new value
})
value = $.Deferred(function resolver(d){ d.resolve(4); }).promise();
squared = value.then(function(val) { return val*val; });
squared.done(function(sq) {
console.log("squared value: "+ sq);
});
$.when(p1, p2, ... pn) returns a new promise which will resolve the values of the resolved promises.
$.when(p1,p2,p3).done(function allDone(v1,v2,v3) {
// All promises have been resolved
// do something with v1, v2 and v3
});
$.when(p1,p2,p3).fail(function rejected(reason) {
// one of the the promise was rejected
});
var login = $.post("/login", {username: "Twilight", password: "Sparkle"})
Step 2
: get the feeds' idsresponse to login:
{
"user_id": "123",
"feeds_ids": [
2, 3, 5
]
}
var feedsIds = login.then(function(response) {
return response.feeds_ids;
});
var articles = feedsIds.then(function gatherArticles(ids) {
return ids.map(function getArticles(id) {
return $.getJSON("/api/feeds/"+id+"/latest");
});
});
//articles is an array of promises
[
promise for getJSON(/api/feeds/1/latest),
promise for getJSON(/api/feeds/2/latest),
promise for getJSON(/api/feeds/3/latest)
]
var allArticles = $.when.apply($, articles);
var total = allArticles.then(function computeTotal() {
var articles = [].slice.call(arguments);
return articles.reduce(function sum(acc, val) {
return acc + val.length;
},0);
});
total.done(function displayTotal(total) {
target = document.getElementById("#totalArticles");
totalDiv = document.createElement('div');
totalDiv.textContent = "Grand total of "+total+" articles";
target.appendChild(totalDiv);
});
Callbacks based vs promise based vs event based
Pretty different usage from the two others techniques.
This presentation:
http://slid.es/geekingfrog/asynchronous-programming-with-promises
greg@geekingfrog.com