0

Since Javascript is single-threaded, I don't really know how this can be a problem but it goes like this: I have a function that gets called and in it another function. As soon as the Javascript starts executing the inner function, it simultaneously resumes with the outer function, when I actually want it to wait until the inner/nested function is finished and then go on. I hope this was understandable but I will elaborate further in comments:

function foo() {
    "use strict";

    //get some json file
    $.getJSON("bar.json", function(data) {
        //calculate something with data
        //put the result in this div (innerHTML)
    });

    //display: block the div with results   
}

The problem is that it immediately displays the div even if the calculation isn't finished yet. It will then throw in the result later, which is not at all what I want it to do. Do I have to do a promise or something like that?

Thanks in advance for your help. I appreciate it a lot.

leonheess
  • 16,068
  • 14
  • 77
  • 112
  • 2
    Because `$.getJSON` is asynchronous. See [this question](https://stackoverflow.com/questions/2765411/is-it-possible-to-set-asyncfalse-to-getjson-call) to see how to make that call a synchronous one. – Spencer Wieczorek Nov 29 '17 at 22:28
  • 2
    Single-threaded but _asynchronous_ -- you either need to leverage a [callback](https://developer.mozilla.org/en-US/docs/Glossary/Callback_function) pattern, use a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)-based approach, or leverage [`await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await). – Alexander Nied Nov 29 '17 at 22:30
  • @SpencerWieczorek It works fine now but the browser tells me _"Synchronous XMLHttpRequest on the main thread is deprecated [...]"_ - is it bad practice to use `async:false`? – leonheess Nov 29 '17 at 22:52

3 Answers3

1

Being that your $.getJSON() is an asynchronous action, you'll need to use a Promise to get your desired result. In the then block is where you want to do the display block with results. Alternatively this could all be done in your $.getJSON() block though. If you need the latter, here's how you'd do it:

function foo() {
    "use strict";

    //get some json file
    new Promise(function(resole, reject) {
      $.getJSON("bar.json", function(data) {
        //calculate something with data
        //put the result in this div (innerHTML)
        resolve(data)
      });
    }).then(function(data) {
       //display: block the div with results
    });
}
Carl Edwards
  • 13,826
  • 11
  • 57
  • 119
0

You shouldn't attempt to block your main thread. Instead, move the logic that changes the display:block of your div inside of your callback that is run after the JSON is fetched like so:

function foo() {
    "use strict";

    //get some json file
    $.getJSON("bar.json", function(data) {

        //calculate something with data
        //put the result in this div (innerHTML)

        //display: block the div with results   
    });

    // will continue executing 
}
Christian Santos
  • 5,386
  • 1
  • 18
  • 24
0

Very helpful link by Spencer Wieczorek. I changed the code to:

function foo() {
   "use strict";

   //get some json file
   $.ajax({
     url: "bar.json",
     dataType: 'json',
     async: false,
     data: data,
     success: function(data) {
       //calculate something with data
       //put the result in this div (innerHTML)
     }
   });
   //display: block the div with results 
}

It seems to work now. Thanks a lot for teaching me this better way of getting a JSON.

leonheess
  • 16,068
  • 14
  • 77
  • 112