jQuery Deferred, Promises and $.when()
Some tasks take time: Ajax requests, animations, timers. A promise is an object which represents the result of such a task, which will come later. jQuery has used promises for many years, in Ajax and in animations, and it has its own object $.Deferred.
Ajax methods return promises
You already used this in the Ajax chapter: .done() runs on success and .fail() on error.
{ "name": "File A" }
{ "name": "File B" }
<p>Page</p>
$.when(): wait for many tasks
$.when() waits for all the given promises, and then runs .done() with all the results.
var a = $.getJSON('a.json');
var b = $.getJSON('b.json');
$.when(a, b).done(function (resA, resB) {
console.log('A: ' + resA[0].name);
console.log('B: ' + resB[0].name);
console.log('Both requests are complete');
});
A: File A
B: File B
Both requests are complete
For Ajax requests, each result is an array: [data, status, jqXHR], so we read resA[0] for the data.
Create your own with $.Deferred()
function wait(ms) {
var d = $.Deferred();
setTimeout(function () {
d.resolve('waited ' + ms + ' ms');
}, ms);
return d.promise();
}
wait(30).done(function (msg) { console.log(msg); });
$.when(wait(20), wait(40)).done(function (m1, m2) {
console.log(m1 + ' and ' + m2);
});
waited 30 ms
waited 20 ms and waited 40 ms
d.resolve(value)says the task is successful.d.reject(reason)says the task failed.d.promise()gives a read-only version to return to other code.
Reject and fail
function check(n) {
var d = $.Deferred();
if (n > 0) d.resolve('OK ' + n); else d.reject('n must be positive');
return d.promise();
}
check(5).done(function (v) { console.log(v); });
check(-1).fail(function (e) { console.log('Error: ' + e); });
OK 5
Error: n must be positive
then() and chaining
$.getJSON('a.json')
.then(function (data) {
console.log('First: ' + data.name);
return $.getJSON('b.json'); // return another promise to continue
})
.then(function (data) {
console.log('Second: ' + data.name);
})
.catch(function () {
console.log('A request failed');
});
First: File A
Second: File B
jQuery promises and native Promises
Since jQuery 3, the promises follow the Promises/A+ standard, so .then() works like the native one, and you can use them with async and await:
async function load() {
var a = await $.getJSON('a.json');
var b = await $.getJSON('b.json');
console.log(a.name + ' + ' + b.name);
}
load();
File A + File B
For new code, many people prefer the native fetch() and Promise.all(). The jQuery slim build (without Ajax and effects) does not include Deferred. See jQuery vs Vanilla JavaScript.
| Exercises & Assignments |
|---|
| No Content Found. |
| Interview Questions & Answers |
|---|
| No Content Found. |