jQuery.when understanding

98,007

Solution 1

function showData(data1, data2) {
    alert(data1[0].max_id);
    alert(data2[0].max_id);
}

function method1() {
    return $.ajax("http://search.twitter.com/search.json", {
        data: {
            q: 'ashishnjain'
        },
        dataType: 'jsonp'
    });
}

function method2() {
    return $.ajax("http://search.twitter.com/search.json", {
        data: {
            q: 'ashishnjain'
        },
        dataType: 'jsonp'
    });
}

$.when(method1(), method2()).then(showData);​

Here's a working jsFiddle

Solution 2

The problem is that you're passing showData() to then(), not showData. You should pass a reference to a function to .then():

$.when(method1(), method2())
    .then(showData);

or

$.when(method1(), method2())
    .then(function () {
        showData();
    });

Edit

I've put together a working demo. Part of the problem (at least in the code fragment you posted) was that there was no callback function named $callback. Part of the problem was the $ in the callback name '$callback'.

So, remove the jsonp: '$callback' ajax option, so that jQuery defaults to a callback function named callback, and define a function with that name, and it all works.

Share:
98,007
Ashish
Author by

Ashish

Updated on August 09, 2020

Comments

  • Ashish
    Ashish over 3 years

    I am trying to use the jQuery.when to fire two ajax requests and then call some function after the two requests have completed. Here's my code:

    var count = 0;
    var dfr;
    
    var showData = function(data) {
        dfr.resolve();
        alert(count);
       // Do something with my data data received
    };
    
    var method1 = function() {
        dfr = $.Deferred();
    
        return $.ajax('localhost/MyDataService/DataMethod_ReturnsData', {
            dataType: "jsonp",
            jsonp: "$callback",
            success: showData
        });
    };
    
    var method2 = function() {
        return $.ajax('localhost/MyDataService/DataMethod_ReturnsCount', {
            dataType: "jsonp",
            jsonp: "$callback",
            success: function(data) {
                count = data.d.__count;
            }
        });
    };
    
    $.when(method1(), method2())
        .then(showData());
    

    However this is not working as expected. Ajax call in method1 will return data which is to be used in showData() and Ajax call in method2 will return count which is to be assigned to var count and later used in showData().

    But when I fire the above code, method1 gets called and then method2 and then showData leaving the data in showData as 'undefined'. How can I achieve this via $.when which as far as I know proceeds only when both functions returning $.promise are executed. I want that both the ajax calls should be called in parallel and later results be displayed based on results from both calls.

  • Ashish
    Ashish about 13 years
    This does not answers my query as the countReponse will loose any one of the data, either count or actual data, since the ajax calls in method1 and method2 are asynchronous. Whatever call executes later will have data but the first data will be lost.
  • Ashish
    Ashish about 13 years
    Tried both ways but still the same. data parameter in showData is still 'undefined'
  • Matt Ball
    Matt Ball about 13 years
    See my edit. There were at least 2 other problems in your code.
  • Alnitak
    Alnitak about 13 years
    the point of jQuery deferreds is so that you don't have to count the number of responses before proceeding.
  • Alnitak
    Alnitak about 13 years
    yup, looks right to me - if you call .then(showData()) it will execute showData immediately and then pass its result to .then. As Matt says - pass the function reference.
  • Matt Ball
    Matt Ball about 13 years
    Agreed with previous two comments. This does not answer the question at all - esp. since it doesn't use jQuery deferreds.
  • Ashish
    Ashish about 13 years
    Thanks a lot Matt. With the help of your sample I put across a working sample here [jsfiddle.net/f4hmL/3/].
  • Ashish
    Ashish about 13 years
    That's gr8. Thanks. However what I saw after implementing it in my internal code is that, I get data1 and data2 same. That means, I can remove data2 and use data1 object. Data1 comes out to be [Object], "success", [Object]. The 1st [Object] is response from my first ajax call, "success" is string, and 2nd [Object] is response from my second ajax call. I can evaluate it as data1[0].d. However data1[2].responseText is the result from 2nd ajax call. Why do we get responseText rather than data[2].d? Any suggestions?
  • Haresh Vidja
    Haresh Vidja about 13 years
    Sorry Ashish for my misunderstanding because you have not mentioned both of response is need to store.
  • Guillaume86
    Guillaume86 about 13 years
    looks weird, data1 should be an array containing the arguments of the m1() success callback, and data2 an array with the args of the m2() callback
  • HarryFink
    HarryFink over 10 years
    In the case where multiple Deferred objects are passed to jQuery.when, the method returns the Promise from a new "master" Deferred object that tracks the aggregate state of all the Deferreds it has been passed. Quote from manual.
  • Guillaume86
    Guillaume86 over 10 years
    Doesn't explain how the master deferred is resolved arguments wise, wich is what was asked over 2 years ago ;)
  • oligofren
    oligofren over 10 years
    The fiddle does not work. Blocked a frame with origin "fiddle.jshell.net" from accessing a frame with origin "jsfiddle.net". Protocols, domains, and ports must match.
  • Guillaume86
    Guillaume86 over 10 years
    Chrome updates broke a lot of fiddles that were using raw.github urls. You can just find alternative urls for the scripts and it should be OK.
  • Mathew Magante
    Mathew Magante about 4 years
    @Guillaume86 hello, it is possible to create dynamic method()? for example I can use 2 method or 3 base on the condition meet.
  • Guillaume86
    Guillaume86 about 4 years
    Use Promise.all( arrayOfPromises )
  • SoftwareDveloper
    SoftwareDveloper over 2 years
    Great solution. I have a question: how do I pass parameters to method1 and method2 in the when call?