I want to queue multiple asynchronous ajax requests using deferred/promise implementation of jquery:
function doSomething() {
console.log('doSomething')};
function makeMultiAjaxRequests1() {
console.log('makeMultiAjaxRequests1')};
function makeMultiAjaxRequests2() {
console.log('makeMultiAjaxRequests2')};
var step1 = function () {
var promise = new $.Deferred().promise();
makeMultiAjaxRequests1();
return promise; }
var step2 = function () {
var promise = new $.Deferred().promise();
makeMultiAjaxRequests2();
return promise; }
step1()
.then(step2())
.done(doSomething());
$.when(step1(),
step2())
.done(function () {
doSomething();
});
Here is the fiddle link. So my question is:
In the pattern where step1 and step2 are executed in parallel, the code does not reach the last handler function. Why?
Use of setTimeout() function: In order to wait for a promise to finish before returning the variable, the function can be set with setTimeout(), so that the function waits for a few milliseconds.
The keyword await is used to wait for a Promise. It can only be used inside an async function. This keyword makes JavaScript wait until that promise settles and returns its result.
In this approach, we will use Promise. all() method which takes all promises in a single array as its input. As a result, this method executes all the promises in itself and returns a new single promise in which the values of all the other promises are combined together.
Using Promise.all()Promise.all waits for all fulfillments (or the first rejection).
You need to resolve the deferred
obj in step1 and step2
Try this
function doSomething() {
console.log('doSomething')};
function makeMultiAjaxRequests1(deferred) {
console.log('makeMultiAjaxRequests1')
deferred.resolve()};
function makeMultiAjaxRequests2(deferred) {
console.log('makeMultiAjaxRequests2')
deferred.resolve()};
var step1 = function () {
var deferred = new $.Deferred();
makeMultiAjaxRequests1(deferred);
return deferred; }
var step2 = function () {
var deferred = new $.Deferred();
makeMultiAjaxRequests2(deferred);
return deferred; }
step1().then(step2).done(doSomething);
$.when(step1(), step2()).done(function () {
doSomething();
});
@Daiwei gives a good answer.
A common gist to be referred to is https://gist.github.com/sergio-fry/3917217 by sergio-fry.
Should you want to have a more dynamic approach where you don't know beforehand how many arguments you are running parallel, here is a good example extension of JQuery (1.10+):
$.whenAll = function (deferreds) {
function isPromise(fn) {
return fn && typeof fn.then === 'function' &&
String($.Deferred().then) === String(fn.then);
}
var d = $.Deferred(),
keys = Object.keys(deferreds),
args = keys.map(function (k) {
return $.Deferred(function (d) {
var fn = deferreds[k];
(isPromise(fn) ? fn : $.Deferred(fn))
.done(d.resolve)
.fail(function (err) { d.reject(err, k); })
;
});
});
$.when.apply(this, args)
.done(function () {
var resObj = {},
resArgs = Array.prototype.slice.call(arguments);
resArgs.forEach(function (v, i) { resObj[keys[i]] = v; });
d.resolve(resObj);
})
.fail(d.reject);
return d;
};
See the code in action with a dynamic live example:
http://jsbin.com/nuxuciwabu/edit?js,console
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With