0

Both of the functions are $.getJSON() functions, and even though my first function is placed before the other one, it sometimes occurs after the second one. Note that I mentioned "sometimes". When I keep refreshing the page, I get different results, and it's like it's randomly being chosen which function is called first. Here is the snippet of code:

timeClusters = [];
$.getJSON('java_output/tasksTab.json', function (data) {
  console.log ("first");
  // Method stuff here, not important
});

$( document ).ready(function() { 
  console.log("second");
  // Method stuff here, not important
});

Now, when I run the program and look at the console, sometimes I get

first
second

but other times I get

second
first

It is essential that I get the first one first, and second second, because the second method processes data that is produced and altered in the first method.

Let me know if you need more information

Ende Neu
  • 15,581
  • 5
  • 57
  • 68
StoneMan
  • 423
  • 3
  • 18
  • 2
    That's how Javascript works. `$.getJSON` will call your callback when it's done, as `ready()` will fire when it's ready. It's called [non-blocking](http://en.wikipedia.org/wiki/Asynchronous_I/O). – jeremyharris Aug 06 '14 at 23:21
  • @jeremyharris So what can I do to ensure that the "second" function ALWAYS executes after the first one has? – StoneMan Aug 06 '14 at 23:22
  • @user3ffgfgfgfgfg50064 The answers given for "[Can I get a jQuery Deferred on document.ready()?](http://stackoverflow.com/questions/6177187/can-i-get-a-jquery-deferred-on-document-ready)" would probably do well for that. – Jonathan Lonowski Aug 06 '14 at 23:25
  • Can't you just create a function instead of having the document ready, and call this once the first method has finished? Or am I missing the point? – Radderz Aug 06 '14 at 23:28
  • @JonathanLonowski - I believe `document.ready` executes the callback *if* the DOM is ready, even at a later time, so you could just stick a `document.ready` handler inside the callback for the ajax request to make sure the DOM is ready, but thats ugly, and putting the ajax call inside `document.ready` sure looks better, even if it can be a little slower. – adeneo Aug 06 '14 at 23:40

1 Answers1

1

The getJSON method is Asynchronous, that means that once started it will eventually hold a result, the function wrapped in document ready instead fires as soon as the DOM is ready, instead of doing this sequence of action you should move the code form the ready function to the getJSON callback:

$(document).ready(function() {
  $.getJSON('java_output/tasksTab.json', function (data) {
    console.log ("first");
  }).done(function() {
    console.log( "second" );
  })
})

As adeneo pointed out you don't actually need to chain the done method, you can simply add the computation in the default callback:

$(document).ready(function() {
  $.getJSON('java_output/tasksTab.json', function (data) {
    console.log ("first");
    console.log( "second" );
  })
})

Other kinds of callback you can use are fail and always.

Ende Neu
  • 15,581
  • 5
  • 57
  • 68
  • Thanks man, works well. Coming from a JAVA background, I'm very unfamiliar with the asynchronous behavior and functionality these kind of functions. Do you know any good resources for understanding them and the nature of callback functions? – StoneMan Aug 06 '14 at 23:26
  • Both those callbacks are the same, I don't get it ? Also, moving the code from the `ready` function to the callback for the ajax call does not guarantee that the DOM is ready ? – adeneo Aug 06 '14 at 23:27
  • 1
    I like [this documentation](http://msdn.microsoft.com/en-us/library/windows/apps/hh700330.aspx) for async functions. – Ende Neu Aug 06 '14 at 23:29
  • @adeneo No moving the code inside the callback doesn't guarantee that the DOM is ready, most likely it will work only because the HTTP request will be slower than the DOM loading, if that's a problem OP can wrap the whole `getJSON` inside a document ready. For the callbacks, they are called in different way, if the HTTP request doesn't return an OK status code, fail will be called, else done and always is always called. – Ende Neu Aug 06 '14 at 23:33
  • But the OP claims that the console logs in his code logs randomly, so clearly the ajax call sometimes finishes before the DOM ready handler is called, which makes this an issue, and doesn't really solve the problem. As for the callbacks, they are exactly the same, the built in callback function is for `success`, which in other words is exactly the same as the chained on `done`, they do the exact same thing, but now you have two of them ? – adeneo Aug 06 '14 at 23:35
  • From the docs: "The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callback methods introduced in jQuery 1.5 are deprecated as of jQuery 1.8.", so success is deprecated in newest jQuery version. As for the DOM, you are correct, I will edit my answer. – Ende Neu Aug 06 '14 at 23:37
  • You're not really getting it, the callback function in `$.getJSON` where you're calling the first console log is exactly the same as the chained on `done` function, they do the exact same thing, so you have two callbacks that do the exact same thing, and I still don't see how this solves anything, but based on upvotes I'm obviously wrong, so it doesn't matter. – adeneo Aug 06 '14 at 23:42
  • @adeneo I see what you mean now, in effect you don't need the done, you could already use the standard callback which returns data avoiding one chain, sorry, my bad, I really got to get some sleep. The functionality anyway is the same, simply done is called after the first callback is finished, without done though I could save a callback chain, so yes you were right. – Ende Neu Aug 06 '14 at 23:42
  • 1
    And then you're back to the same code the OP has, except you've moved both console logs into the same callback, which would obviously print the logs to the console in the right order, but doesn't really solve anything. And now you've added `document.ready`, and it's the same as the other answers, and one wonders what people where upvoting ? – adeneo Aug 06 '14 at 23:43
  • Actually it's different form OP, if you see the two console log are wrapped in different functions, since their execution can be concurrent you don't know how will the values be printed, when you move the print inside the getJson callback though you are sure that the code is executed sequentially and that's what the OP wants, he wants to be able to decide the sequence of actions to be executed without incurring in non deterministic situations, specifically he wants to get back the json before doing anything else. – Ende Neu Aug 06 '14 at 23:47
  • And again, that's what the other answers do, yours however didn't, it just had two callbacks, and one still wonders what people were upvoting, but it doesn't matter. – adeneo Aug 06 '14 at 23:48
  • In my first answer the `done` is invoked _after_ the getJSON default callback so the logs will be executed in order, getJSON invokes the default callback, if the return code is ok invokes done, else fail and then always, from the [docs](http://api.jquery.com/jquery.getjson/): "The Promise interface in jQuery 1.5 also allows jQuery's Ajax methods, including $.getJSON(), to chain multiple .done(), .always(), and .fail() callbacks on a single request, and even to assign these callbacks after the request may have completed. If the request is already complete, the callback is fired immediately". – Ende Neu Aug 06 '14 at 23:52
  • This answer indeed syncs up the console.log() lines but I see what @adeneo is saying. If the original question is why were the console.log() lines seemingly in random order, it was because the `$.getJSON` is fired on page load (outside `.ready()`) and could finish before or after the DOM is ready, depending on outside factors. This answer illustrates how to keep them in sync so you don't have to worry about the race condition. – TrazeK Aug 07 '14 at 17:44
  • @TrazeK I feel like I'm really missing something which I would like to understand. The incipit to my answer is: "_The getJSON method is Asynchronous, that means that once started it will eventually hold a result, the function wrapped in document ready instead fires as soon as the DOM is ready_", your comment says: "_it was because the $.getJSON is fired on page load (outside .ready()) and could finish before or after the DOM is ready, depending on outside factors._", are this two statements different or maybe mine was not clear? Because that's exactly what I meant. Thanks for the patience. – Ende Neu Aug 08 '14 at 06:30
  • No, I think everyone is on the same page now. Good luck! – TrazeK Aug 08 '14 at 07:11