-2

Need JS to wait until the ajax completes(i.e. ajax success function executes), but Ajax is executing after the calling function completes. Added a callback but did not help. Log statements are inserted in the code to record the order. Currently, the order is:

  • 1: 11ms
  • 2: 3ms
  • 3: 10ms
  • 5: 32ms
  • 7: 13ms
  • 4: 23ms
  • 6: 5ms

Need it to execute in numeric sequential order "1 to 7".

HTML:

<script>
    $(document).ready(function(){
        $('#btn').click(function() {
            console.log('1');
            callAjaxfunc();
            console.log('7');
        });
    });
</script>

<button id="btn">Call Ajax!</button>
<div id="log"></div>
<div id="info"></div>

JS:

function callAjaxfunc() {
    console.log('2');
    callingAjaxfunc(function() {
        console.log('6');
    });
}

function callingAjaxfunc(callback) {
    console.log('3');   
    $.ajax({
        url: 'https://api.joind.in/v2.1/talks/10889',
        data: {
        format: 'json'
        },
        error: function() {
            $('#info').html('<p>An error has occurred</p>');
        },
        dataType: 'jsonp',
        success: function(data) {
            var $title = $('<h1>').text(data.talks[0].talk_title);
            var $description = 
            $('<p>').text(data.talks[0].talk_description);
            console.log('4');
            callback();
            $('#info')
                .append($title)
                .append($description);
        },
        type: 'GET'
    });

    console.log('5'); 
}
B. Fleming
  • 7,170
  • 1
  • 18
  • 36
javaCoder
  • 37
  • 5
  • You need to do some research into what asynchronous logic is (which ajax is) and why it is a bad idea to try to force the paradigm into synchronous logic. – Taplar Nov 29 '18 at 20:13
  • Ref. https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – Taplar Nov 29 '18 at 20:14
  • Re-order your console.logs such that they log in the order you wanted them to. – Kevin B Nov 29 '18 at 20:24
  • Understood, but why wouldn't a callback work. I need to get it to work as is. I could place async: false and async: true, but it is not recommended. that's why I wanted to use a callback. – javaCoder Nov 29 '18 at 20:25
  • It isn't possible. Callbacks for asynchronous methods are... ***asynchronous*** No amount of callback/promise/asyncawait magic will change that. – Kevin B Nov 29 '18 at 20:26
  • The correct order requested is 1, 2, 3, 4, 5, 6, 7; it should execute in numeric order. – javaCoder Nov 29 '18 at 20:27
  • Right. so re-number your console.logs. – Kevin B Nov 29 '18 at 20:27
  • Kevin, why does async: false and async: true work? – javaCoder Nov 29 '18 at 20:28
  • async:false works because it pauses the entire thread until the ajax is complete. This is bad because the UI also depends on said thread. By pausing the thread, you're essentially locking down the browser which will make the page appear to be broken. Tabs cant be swapped between, gifs won't play, videos won't play, music stops, etc. Everything stops. The page won't even render html changes while waiting for the request to complete. – Kevin B Nov 29 '18 at 20:29
  • async: false is also deprecated by jQuery (and removed entirely in 3X), and **browsers** are also deprecating it. – Taplar Nov 29 '18 at 20:30
  • Then there's the fact that async: false is deprecated because browsers are removing that functionality. – Kevin B Nov 29 '18 at 20:30
  • Kevin, missed your question. I need it to execute in sequential order; that is, htm calls callAjaxfunc, which callscallingAjaxfunc function, which makes an ajax call, then returns to callAjaxfunc. – javaCoder Nov 29 '18 at 20:47
  • Why do you need to execute an async function as a sync? So if it's just to you feel in control about what is happening, you can use Promise. – JmLavoier Nov 29 '18 at 21:51

1 Answers1

0

There are 2 way to you keep in control of the sequence code. First, understanding that you're working with an async function, you can put the sequence of you code within the success callback.

HTML

<script>
  $(document).ready(function(){
    $('#btn').click(function() {
      console.log('1');
      callAjaxfunc(function() {
        console.log('7');
      });

    });
  });
</script>

<button id="btn">Call Ajax!</button>
<div id="log"></div>
<div id="info"></div>

JS

function callAjaxfunc(callback) {
  console.log('2');
  callingAjaxfunc(function() {
    console.log('5'); 
    console.log('6');
    callback();
  });
}

function callingAjaxfunc(callback) {
  console.log('3');   
    $.ajax({
      url: 'https://api.joind.in/v2.1/talks/10889',
      data: {
       format: 'json'
      },
      error: function() {
        $('#info').html('<p>An error has occurred</p>');
      },
      dataType: 'jsonp',
      success: function(data) {
        var $title = $('<h1>').text(data.talks[0].talk_title);
        var $description = 
        $('<p>').text(data.talks[0].talk_description);
        console.log('4');
        callback();
        $('#info')
            .append($title)
            .append($description);
      },
      type: 'GET'
   });
}

I've just put your code in sequence, but that's not a good practice. So don't do it. You must understand that you're working with asynchronous code, so accepting the async way is better.

I encourage you to learn more about Promises(async/await) or Generators. It could be a good way to you be better on implementing async code best practices.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise https://jakearchibald.com/2017/async-iterators-and-generators/

JmLavoier
  • 523
  • 5
  • 9