0

My problem is b() executing lastly, but it should be 2nd in the order. I want to call a JSON api on every click on a button (and always send new api call), but it should remove the last api message from the div:

$(document).ready(function() {

  function test() {

    function a() {
      $("#message-quote, #message-person").empty();
      console.log('p1');
    };

    function b() {
      console.log('p2 - before getJSON');
      $.getJSON("http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&callback=", function(a) {
        $("#message-quote").append(a[0].content)
        $("#message-person").append("<p>— " + a[0].title + "</p>")
        console.log('p2 - in getJSON');
      });
    };

    function c() {
      $("body, .button, .quote-icons a").css("background-color", "red");
      $(".quote-text").css("color", "red");
      console.log('p3');
    };

    var d = $.Deferred(),
    p = d.promise();
    p.then(a()).then(b()).then(c());
    d.resolve();
  };

  $("#getMessage").on("click", function() {
    test();
  });

});

The order I got is:

"p1"
"p2 - before getJSON"
"p3"
"p2 - in getJSON"
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Lanti
  • 2,299
  • 2
  • 36
  • 69
  • 1
    Are you *sure* `b()` is running last? Are you basing this assertion on the console output? Because a()-b()-c() *will* give you output p1-p3-p2. If you remove the promise and just call `a();b();c()` you'll get "p1 p3 p2". Confirm this by adding a console.log *before* the `$.getJSON`. – freedomn-m Sep 02 '16 at 13:24
  • I updated my question. – Lanti Sep 02 '16 at 13:29
  • In `b()` add a return, ie: `return $.getJSON(...` – freedomn-m Sep 02 '16 at 14:21
  • Question: do you understand *why* it goes in this order? and you're trying to get it to work with `.then()`? – freedomn-m Sep 02 '16 at 14:22
  • Possible duplicate of [How do I chain a sequence of deferred functions in jQuery 1.8.x?](http://stackoverflow.com/questions/13651243/how-do-i-chain-a-sequence-of-deferred-functions-in-jquery-1-8-x) – Heretic Monkey Sep 02 '16 at 15:12

1 Answers1

1

Your not waiting for the return of b(), you need to chain the promises due to it calling Asynchronously.

if you return a promise out of b(), it should then wait for result of getJSON to be return before it continues.

also, your functions are executing straight away, .then(callback) needs to take a function it can execute later, where your executing a function straight away instead

function b() {

      return $.getJSON("http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&callback=", function(a) {
        $("#message-quote").append(a[0].content)
        $("#message-person").append("<p>— " + a[0].title + "</p>")
        console.log('p2');
        // resolve the promise, the call has been completed
      });
    };

 var d = $.Deferred(),
    p = d.promise();
    p.then(a)
     .then(b)
     //the context of .then will now be the promise out of b()
     .then(c);
    d.resolve();

Note : Promises will need to also be returned form each other method.

EDIT: as Rocket pointed out, jQuery Ajax calls implement the promise methods

working example : https://jsfiddle.net/rsfxpg38/4/

you can see an example of it from this post : How do I chain a sequence of deferred functions in jQuery 1.8.x?

Community
  • 1
  • 1
Reiss Jarvis
  • 151
  • 8
  • I placed your code in function `b()`, but the execution order same as before. – Lanti Sep 02 '16 at 14:18
  • ive got a working example on jsFiddle, i've corrected my mistake – Reiss Jarvis Sep 02 '16 at 15:05
  • The execution order in the jsfiddle console is: `ifac initialized! - p1show - p2 - before getJSON - p3show - p2` `p2` should come before `p2 - before getJSON` – Lanti Sep 02 '16 at 15:07
  • have you cleared your cache for the example ive shown? ive now included a 10 second delay and i get the results you need https://jsfiddle.net/rsfxpg38/3/ – Reiss Jarvis Sep 02 '16 at 15:15
  • You don't need to use `$.Deferred` inside `b()`. You can just `return $.getJSON(...);`. All the AJAX methods implement the promise methods (in jQuery). – gen_Eric Sep 02 '16 at 15:20
  • Thank You! Your solution works. This is the final fiddle: https://jsfiddle.net/rsfxpg38/10/ – Lanti Sep 02 '16 at 16:27