0

Problem that I'm trying to solve: I want to have two arrays of ajax functions. One with topPriority that should run first, and another one with low priority that will start as soon as ALL of the topPriority calls are done.

However, this functions are not even called in the $.when line. Am I using this correctly?

//Html:

<div id="foo">Hello World</div>

//CSS:

#foo{ border:1px solid red; padding:10px; display:none }

//Javascript:

// open your console!

function getData(){
   return $.get('/echo/html/');
}

function showDiv(){
    var dfd = $.Deferred();

    $('#foo').fadeIn( 1000, dfd.resolve );

    return dfd.promise();
}

var topPriorityFunctions = new Array();
topPriorityFunctions.push(showDiv);
topPriorityFunctions.push(getData);

$.when.apply($, topPriorityFunctions )
    .then(function( ajaxResult ){
        console.log('The animation AND the AJAX request are both done!');

        // ‘ajaxResult’ is the server’s response
        // start my lowPriorityTasks.
    });

Here is the fiddle with all this code in order to be able to test it an modify it.

References: I tried to modify from the working example on this page in order to solve my problem.

Cacho Santa
  • 6,846
  • 6
  • 41
  • 73
  • Don't pass `dfd.resolve` directly as the callback. `resolve()` will be invoked with `this` bound to `$("#foo")[0]` instead of `dfd`, which will most probably break the implementation. Pass an anonymous function that calls `dfd.resolve()` instead. – Frédéric Hamidi Feb 25 '15 at 14:03
  • 1
    Note: you can change `$('#foo').fadeIn( 1000, dfd.resolve )` to simply `return $('#foo').fadeIn(1000).promise()` as that will return the animation queue promise – iCollect.it Ltd Feb 25 '15 at 14:09
  • thanks @frédéricHamidi. I don't understand quite well you explanation. Why are my functions not even called? I really don't care to much about the function showDiv being a Deferred object, since my problem is actually a bit different. ALL of my functions are just ajax calls. – Cacho Santa Feb 25 '15 at 14:09
  • @cacho, looks like a fiddle problem. With jQuery (edge), my browser says `Blocked loading mixed active content "http://code.jquery.com/jquery-compat-git.js"`. With jQuery 2.1.0 the functions are called. – Frédéric Hamidi Feb 25 '15 at 14:12
  • 1
    @TrueBlueAussie, assuming no other animations are started on `#foo` during the 1 second delay, yes. – Frédéric Hamidi Feb 25 '15 at 14:13
  • @Frédéric Hamidi: True. It will depend on the specific case. – iCollect.it Ltd Feb 25 '15 at 14:17
  • @FrédéricHamidim, I have updated the jsfiddle to reflect the code posted in my questions. I can't get it to work with JQuery 2.1 either :O/ – Cacho Santa Feb 25 '15 at 14:19

1 Answers1

3

$.when does not accept or expect an array of functions, it expects an array of deferreds. You need to invoke your functions, and pass the promises in.

var topPriorityPromises = [];
topPriorityFunctions.push(showDiv());
topPriorityFunctions.push(getData());

$.when.apply($, topPriorityPromises ).then(function () {
  // ...

If you simplify this and ignore the array/apply portions, you would be invoking when this way, which is wrong:

$.when(showDiv, getData);

not this way, which is correct:

$.when(showDiv(), getData());
user229044
  • 232,980
  • 40
  • 330
  • 338
  • thanks @meagar. The thing is I actually do not need a Deferred function, I just have an array of 10 ajax calls. But, I need 3 of them to finish first (top priority), and then I want to call the rest of the 7 ajax calls (low priority). – Cacho Santa Feb 25 '15 at 14:29
  • In that case, can I still use $.when.apply( ) with an array of ajax calls functions? – Cacho Santa Feb 25 '15 at 14:30
  • You have 3 urls which can work independently and other 7 depends on accumulated response of first 3. Is that what you want? BTW check this as well..https://jsfiddle.net/JSw5y/1168/ – Vishwanath Feb 25 '15 at 14:37
  • @Vishwanath no, actually ALL of the requests can run independently. I just want to give 3 of them a TOP priority because I want them to complete first. – Cacho Santa Feb 25 '15 at 14:40
  • 1
    @cacho That has nothing to do with $.when or the code you've posted in your question. You cannot use `$.when` to "boost" the priority of your AJAX calls. Just *do them first*. My answer answers the question you asked, which is why `$.when` doesn't invoke your functions. If you want to start discussions around this priority concept, ask a new question. – user229044 Feb 25 '15 at 14:41