javascript setInterval: do calls overlap?

2019-03-18 14:25发布

问题:

Suppose I have setInterval(PostToServer, 1000);. PostToServer function makes ajax post, which may take longer than a second. So what happens then: a second call is made while the first hasn't finished or the end of call is awaited before making new one?

回答1:

The calls overlap.

setInterval ensures that the functions are run regularly, without waiting for the previous result.

If you want to await the response, change the interval method to a poller. When the time has passed AND the server has already responded, request again.

Since the server response won't change too much right after the response, you can also add a setTimeout handler in the callback function of your AJAX method.



回答2:

Javascript is single threaded (except for HTML5 web workers which are not involved in this issue) with an event queue. A subsequent call from setInterval() will never start until the previous call is done. Only one can ever be active at a time.

When the time for your interval occurs, internal to the JS engine the timer fires and an event is added to the javascript event queue. When the currently running JS thread of execution finishes (and not before), the JS engine goes and fetches the next event from the event queue and starts that thread of JS execution. Thus two executing paths in JS will never overlap or be going on at the same time. So, two function calls from setInterval() will never overlap. The second one won't start until the first one is done executing.

But, relative to your question, what this means is that two intervals from setInterval() will never overlap, but if you're making an asynchronous ajax call on the first interval timer and the starting of the ajax call finishes right away, and the second interval fires before the first asynchronous ajax call has fired it's completion function, then your ajax calls will or can overlap.

If you wanted to prevent more than one ajax call being in flight at a time, you would have to write some code to specifically prevent that either by not firing the second ajax call until the previous one was completed or by just skipping any ajax call if the previous one is still going.

See this post for more info on the JS event queue and how it works.



回答3:

Yes, it overlaps. You can use setTimeout in the PostToServer function to be sure it don't overlap, but the problem is it runs the request and then wait 1s and then runs the request again. So it don't run every second exactly.

For more information, see this video of Paul Irish: http://youtu.be/i_qE1iAmjFg?t=7m46s