问题
I've read some of the other related questions (Pattern for wrapping an Asynchronous JavaScript function to make it synchronous & Make async event synchronous in JavaScript & there may be more), but I just want to be sure to exhaust all possibilities.
Might it be possible to "convert" an asynchronous XmlHttpRequest into a quasi-synchronous one using either setInterval or setTimeout?
The idea being that upon success of the Ajax request a variable will be set, which will be the signal for a while loop (that has called either setInterval or setTimeout, and a callback function as appropriate) to exit. Or am I fundamentally misunderstanding the abilities (or limitations?) of setInterval and/or setTimeout?
回答1:
It's true, you don't want to use setInterval and setTimeout in the way you've described. What you really want to do is just get comfortable with nested functions, where you can write in a more or less synchronous way.
For example:
XHR.get(your_data, function()
{
//what you would have done "synchronously"
});
While you can use setInterval and/or setTimeout (with calls to setTimeout again in the function body) to "poll" for a success code, that approach is dramatically inferior to just handling the callback in the first place instead of polling for it. It introduces latency, runs away with the CPU, and doesn't scale across multiple XHR requests, to name a few shortcomings.
XHR will call your function when it completes, it makes little sense to run a function asking "Are we done yet? Are we done yet?" in the meantime. On the other hand if there is some periodic behavior you are wanting to BLOCK until the response comes back (a piece of animation that needs that data to run, for example) it is totally acceptable to surround the blocking code in an if statement:
var tick = window.setTimeout(tock, 20);
var tock = function()
{
if (response_done)
{
// dependent code
}
tick = window.setTimeout(tock, 20);
}
XHR.get(your_data, function() { /*Handle response*/ response_done = true; });
回答2:
If I'm getting your question right, you could achieve a similar effect using the following code:
var computationInterval =
window.setInterval(function() {
// do a computation cycle, as if you're in the body of a while loop
}, 100);
$.get('http://example.com/areWeThereYet', function() {
// break the intervals (the pseudo-cycle)
window.clearInterval(computationInterval);
});
来源:https://stackoverflow.com/questions/1809931/simulating-a-synchronous-xmlhttprequest