Reputation: 4845
I'm writing a library to access data from a server, and return formatted data to the consumer of my functions. Here is an example of what I'd like to have:
// my code
var model = function () {
return $.ajax(myRequest).done(function (rawData) {
return treatment(data);
});
}
// client code
var useModel = function () {
var modelPromise = model();
modelPromise.done(function (formattedData) { // consume this result })
}
where formattedData is the result of my first done callback and not the rawData.
Do you have any ideas?
Thanks
R.
Upvotes: 0
Views: 284
Reputation: 2713
Regis,
I like Beetroot's answer a lot. Here's an example I made while trying to understand this concept for myself: Multiple asynchronous requests with jQuery .
Source from jsFiddle:
var logIt = function (msg) {
console.log(((new Date()).toLocaleTimeString()) + ": " + msg);
}, pauseBrowser = function (ms) {
ms += new Date().getTime();
while (new Date() < ms) {}
}, dataForService1 = {
json: JSON.stringify({
serviceNumber: 1,
description: "Service #1's data",
pauseAfterward: 3 // for pausing the client-side
}),
delay: 0 // delay on the server-side
}, dataForService2 = {
json: JSON.stringify({
serviceNumber: 2,
description: "Service #2's data",
pauseAfterward: 1
}),
delay: 0 // delay on the server-side
};
function getAjaxConfiguration() {
return {
type: 'POST',
url: '/echo/json/',
success: function (data) {
var msg = "Handling service #" + data.serviceNumber + "'s success";
logIt(msg);
logIt(JSON.stringify(data));
}
};
}
var async2 = function () {
var ajaxConfig = $.extend(getAjaxConfiguration(), {
data: dataForService2
});
return $.ajax(ajaxConfig);
};
var async1 = function () {
var ajaxConfig = $.extend(getAjaxConfiguration(), {
data: dataForService1
});
return $.ajax(ajaxConfig);
};
var do2AsynchronousFunctions = function () {
var dfd = new $.Deferred();
async1()
.then(function (async1ResponseData) {
logIt("async1's then() method called, waiting " + async1ResponseData.pauseAfterward + " seconds");
pauseBrowser(async1ResponseData.pauseAfterward * 1000);
})
.done(function (a1d) {
logIt("async1's done() method was called");
return async2()
.then(function (async2ResponseData) {
logIt("async2's then() method called, waiting " + async2ResponseData.pauseAfterward + " seconds");
pauseBrowser(async2ResponseData.pauseAfterward * 1000);
})
.done(function (a2d) {
logIt("async2's done() method was called");
dfd.resolve("final return value");
});
});
return dfd.promise();
};
$.when(do2AsynchronousFunctions()).done(function (retVal) {
logIt('Everything is now done! Final return value: ' + JSON.stringify(retVal));
});
Upvotes: 0
Reputation: 18078
Regis,
jQuery's documention for .then() says :
As of jQuery 1.8, the deferred.then() method returns a new promise that can filter the status and values of a deferred through a function, replacing the now-deprecated deferred.pipe() method.
The second example for .then()
is similar to what you want (though not involving ajax).
As far as I can tell, the necessary changes to your code are very minimal :
// my code
var model = function () {
return $.ajax(myRequest).then(function (rawData) {
return treatment(rawData);
});
}
// client code
var useModel = function () {
var modelPromise = model();
modelPromise.done(function (formattedData) { // consume this result })
}
Upvotes: 1