0

Currently I have a function like this:

a: function (val) {
    ajaxcall.done(function() {
        console.log("Done");
    }
}

I want to write another function which calls a, then wait until a is done (so the stuff inside the .done() executes, then it'll continue with the rest. Something like this:

console.log("beginning");
a("test");
console.log("End");

Would that print out

beginning
done
end

or would it sometimes be

beginning
end
done

depending on if the ajax calls take a long time?

Rohinder
  • 143
  • 8
  • just use ajax synchronous call http://stackoverflow.com/questions/133310/how-can-i-get-jquery-to-perform-a-synchronous-rather-than-asynchronous-ajax-re – RomanPerekhrest Apr 07 '16 at 20:43
  • 2
    Try not using sync ajax... You could block the thread unnecessarily. Google Dev Tools actually issue warnings on the console when you start using sync XHR. – noderman Apr 07 '16 at 20:51
  • @roman really really bad idea, not just for the reasons mentioned by noderman, but it's also deprecated because of how bad it is for the experience – Juan Mendes Apr 07 '16 at 21:21
  • @JuanMendes, ok, I think that I would agree with that – RomanPerekhrest Apr 07 '16 at 21:23
  • @vove wrong question, that's talking about the async attribute of the script tag – Juan Mendes Apr 07 '16 at 21:24
  • @JuanMendes, I have not been using JQuery for a long time(prefer native js) and I forgot about such stuff as `$.Deferred`. – RomanPerekhrest Apr 07 '16 at 21:28

4 Answers4

1

That will always print:

beginning
End
Done

Even if the ajax call is instant, because JavaScript always completes the current execution thread before starting another one.

Paul
  • 130,653
  • 24
  • 259
  • 248
1

For the example you provided, it should print the done after the end

To wait for your function to end you can write something like that

a: function(val, done) {
  ajaxcall.done(done)
}

//or if you want to do something before declaring it's done

a: function(val, done) {
  ajaxcall.done(function() {
    console.log('done');
    done();
  })
}

And afterwards use it like that

console.log("beginning");
a("test", function() {
  console.log("End");
});
user3
  • 720
  • 3
  • 14
1

.done() can accept an array of functions to call

function ajaxcall() {
  return new $.Deferred(function(d) {
    setTimeout(function() {
      d.resolve()
    }, Math.random() * 3000)
  }).promise()
}

function complete() {
  console.log("End")
}

function a(val) {
  ajaxcall().done([
    function() {
      console.log("Done");
    },
    complete
  ])
}

a()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
guest271314
  • 1
  • 10
  • 82
  • 156
  • See [`deferred.done( doneCallbacks [, doneCallbacks ] )`](http://api.jquery.com/deferred.done/#deferred-done-doneCallbacks-doneCallbacks) **doneCallbacks** Type: `Function()` _"A function, or array of functions, that are called when the Deferred is resolved."_ – guest271314 Apr 07 '16 at 20:56
0

Use the built in AJAX callback to call your function on complete.

function loadME() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
//if the data is downloaded and you receive no server errors, 
    if (xhttp.readyState == 4 && xhttp.status == 200) {
     yourcallback();
    }
  };
  xhttp.open("GET", "url for your query goes here", true);
  xhttp.send();
} 

Or in jQuery:

$.ajax({
  url: "your api url here",
}).done(function() {
  yourcallback();
});
Korgrue
  • 3,237
  • 1
  • 10
  • 19