最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Wait for completion after multiple promises in parallel using jQuery - Stack Overflow

programmeradmin0浏览0评论

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?

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?

Share Improve this question edited Dec 9, 2013 at 19:54 crishushu asked Dec 9, 2013 at 19:48 crishushucrishushu 5652 gold badges4 silver badges15 bronze badges 3
  • Where are you actually resolving the promise? If you don't trigger the handler, the callback won't be called… – Bergi Commented Dec 9, 2013 at 20:06
  • The Deferreds in step1() and step2() are never resolved. – Beetroot-Beetroot Commented Dec 9, 2013 at 20:09
  • Ya that's true, though what is the case in the previous sequential example? The promise is not resolved and still the code completes. – crishushu Commented Dec 9, 2013 at 22:53
Add a comment  | 

3 Answers 3

Reset to default 7

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

It does reach your done function if you give it a URL it can actually reach (in the case of jsfiddle, that would be say /echo/html/: http://jsfiddle.net/LnaPt/2/

Basically, you just need to do this:

var promise = $.ajax({
    type: "GET",
    url: "/echo/html/",   //<-- instead of google     
}).promise();
发布评论

评论列表(0)

  1. 暂无评论