Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setTimeout for XHR requests

quoting MDC:

If there is a possibility that your logic could take longer to execute than the interval time, it is recommended that you recursively call a named function using window.setTimeout. For example, if using setInterval to poll a remote server every 5 seconds, network latency, an unresponsive server, and a host of other issues could prevent the request from completing in its alloted time. As such, you may find yourself with queued up XHR requests that won't necessarily return in order.

For such cases, a recursive setTimeout pattern is preferred:

(function loop(){
   setTimeout(function(){

      // logic here

      // recurse
      loop();

  }, 1000);
})();

In the above snippet, a named function loop is declared and is immediately executed. loop is recursively called inside setTimeout after the logic has completed executing. While this pattern does not guarantee execution on a fixed interval, it does guarantee that the previous interval has completed before recursing.

I don't understand how this fixes the problem. Shouldn't I call loop() from inside the XHR callback and not from setTimeout?

like image 234
CamelCamelCamel Avatar asked Jul 31 '11 08:07

CamelCamelCamel


People also ask

What is xhr timeout?

The XMLHttpRequest. timeout property is an unsigned long representing the number of milliseconds a request can take before automatically being terminated. The default value is 0, which means there is no timeout.

What is the default timeout for HTTP request?

The default value is 100,000 milliseconds (100 seconds).

How would you set a timeout on an HTTP request?

Timeouts on http. request() takes a timeout option. Its documentation says: timeout <number> : A number specifying the socket timeout in milliseconds. This will set the timeout before the socket is connected.

What is http timeout?

The HyperText Transfer Protocol (HTTP) 408 Request Timeout response status code means that the server would like to shut down this unused connection. It is sent on an idle connection by some servers, even without any previous request by the client.


2 Answers

The original problem is related to setInterval(): it's possible for two or more AJAX requests to be sent before the reply to the first one is received (depending on the network latency and the timer delay). If that happens, their respective callbacks are not guaranteed to be called in order.

The solution is to delay each request independently with setTimeout() and only schedule the next request after the current request has returned (i.e. in that request's callback).

So, you're absolutely right: calling setTimeout() (through loop()) from the delayed function itself only reimplements a poorer setInterval(). You indeed have to call loop() from the AJAX callback to obtain the expected behavior.

like image 139
Frédéric Hamidi Avatar answered Sep 16 '22 17:09

Frédéric Hamidi


The issue at hand is not executing single XHR request but rather repeatedly sending requests to the server at regular intervals.

Suppose you want to poll the server every five seconds and parse the response. You will just use setInterval() for this, causing XHR request to be created and sent every five seconds.

Now if there is some block in traffic or server is slow/overloaded there is chance that request A is sent and the server did not finish to process it when you send request B - that's what they mean by "queued up XHR requests" as far as I understand.

The solution in my opinion is not using setInterval() at all, but rather call the "next" XHR request only from within the callback of the previous request, possibly by using the setTimeout() as well to ensure it will "wait" the proper amount of time before polling again.

like image 30
Shadow Wizard Hates Omicron Avatar answered Sep 19 '22 17:09

Shadow Wizard Hates Omicron