UPDATE Following @Ryan Olds suggestion to include the setTimeout in the callback, I must clarify that in my production code I'm calling multiple urls to get json data from several sites. (Have updated JavaScript code below).
Is it only possible to have multiple timeouts scattered throughout this function?
I have a self-invoking updateFunction as follows:
(function update() {
$.ajax({
type: 'GET',
url: "",
dataType: 'json',
success: function (data) {
// do some callback stuff
},
async: false
});
$.ajax({
type: 'GET',
url: "",
dataType: 'json',
success: function (data) {
// do some further callback stuff
},
async: false
});
setTimeout(update, 2000);
})();
What I expected this code to do
I hoped that this function would go off to the target URL and wait for the result, then deal with the success callback. Then (and only then) would it fall through to set a 2 second timeout to call the function again.
What appears to be happening instead
Instead, the GET request codes out, and before the response has been dealt with, the timeout has already been set.
What am I missing? How can I make this entirely synchronous?
UPDATE Following @Ryan Olds suggestion to include the setTimeout in the callback, I must clarify that in my production code I'm calling multiple urls to get json data from several sites. (Have updated JavaScript code below).
Is it only possible to have multiple timeouts scattered throughout this function?
I have a self-invoking updateFunction as follows:
(function update() {
$.ajax({
type: 'GET',
url: "http://myexample./jsondata",
dataType: 'json',
success: function (data) {
// do some callback stuff
},
async: false
});
$.ajax({
type: 'GET',
url: "http://myexample2./jsondata2",
dataType: 'json',
success: function (data) {
// do some further callback stuff
},
async: false
});
setTimeout(update, 2000);
})();
What I expected this code to do
I hoped that this function would go off to the target URL and wait for the result, then deal with the success callback. Then (and only then) would it fall through to set a 2 second timeout to call the function again.
What appears to be happening instead
Instead, the GET request codes out, and before the response has been dealt with, the timeout has already been set.
What am I missing? How can I make this entirely synchronous?
Share Improve this question edited May 26, 2011 at 21:48 isNaN1247 asked May 26, 2011 at 21:36 isNaN1247isNaN1247 18.1k13 gold badges74 silver badges119 bronze badges 1- You could put setTimeout inside of the success callback for the AJAX call, is one suggestion. You could also use setInterval instead of setTimeout and call it after the main declaration. – g.d.d.c Commented May 26, 2011 at 21:39
5 Answers
Reset to default 6If I were you, I'd make use of jQuery's support for deferred action.
(function update() {
$.when($.ajax({
type: 'GET',
url: "http://myexample./jsondata",
dataType: 'json',
success: function (data) {
// do some callback stuff
}
}), $.ajax({
type: 'GET',
url: "http://myexample2./jsondata2",
dataType: 'json',
success: function (data) {
// do some further callback stuff
}
}), $.ajax({
// more requests as you like
})).then(function() {
// when all the requests are plete
setTimeout(update, 2000);
});
}());
Much nicer, IMHO, than mucking around with synchronous requests. Indeed, if the requests are cross-domain, this is pretty much your only option.
See
$.when
deferred.then
Move the timeout in to the success callback. The request is synchronous, it would appear the the callback is not.
I would modify the setup like so:
function update() {
$.ajax({
type: 'GET',
url: "http://myexample./jsondata",
dataType: 'json',
success: function (data) {
// do some callback stuff
},
async: false
});
$.ajax({
type: 'GET',
url: "http://myexample2./jsondata2",
dataType: 'json',
success: function (data) {
// do some further callback stuff
},
async: false
});
}
setInterval(update, 2000);
update(); // only necessary if you can't wait 2 seconds before 1st load.
You cannot make it entirely synchronous because you're setting up calls to alternate domains. That's done (internal to jQuery) by creating <script>
tags and adding them to the document. Browsers perform those calls asynchronously, and that's that. You can't make ordinary xhr requests to domains different from your own.
I can't imagine why you'd want something like that to be synchronous, especially since you're doing many of these operations.
I don't think async: false
works on cross domain requests.
From the docs: async Boolean Default: true By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active.
In any case, maybe you can set some conditionals to fire the requests in the order that you want.