Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the setInterval() an asynchronous function?

I am making a XMLHttpRequest every second to a server, the server will respond with new messages. To call the XMLHttpRequest every second I use the setInterval() function inside of a SharedWorker.

However, since I am making a request every second, I would like to know if setInterval() is asynchronous or not?

For example, if one XMLHttpRequest request took 3 seconds to finish "due to a delay", will I have 3 requests going at the same time or will setInterval() wait until the first request completes before it waits 1 second and send another request?

Here is my code

function checkQueue(url)
{
  var xhr = new XMLHttpRequest();
  xhr.addEventListener("load", reqListener);
  xhr.open('GET', url, true);
  xhr.send();
}


function reqListener ()
{
    var queue = JSON.parse(this.responseText);
    notifyAllPorts(queue);
    console.log(this.responseText);
}


setInterval(
    function() {
        checkQueue('/add-ons/icws/push.php') 
    }
, 1000);
like image 817
Junior Avatar asked Sep 01 '15 23:09

Junior


3 Answers

Yes, you'll run into trouble. setInterval will go off like clockwork, irrespective of the state of your requests.

You're better-off starting a one hit timer using setTimeout at the completion of every request... so:

function checkQueue(url)
{
  var xhr = new XMLHttpRequest();
  xhr.addEventListener("load", reqListener);
  xhr.open('GET', url, true);
  xhr.send();
}


function reqListener ()
{
    var queue = JSON.parse(this.responseText);
    notifyAllPorts(queue);
    console.log(this.responseText);
    setTimeout(
        function() {
            checkQueue('/add-ons/icws/push.php') 
        }, 1000);
}


checkQueue('/add-ons/icws/push.php') 
like image 100
spender Avatar answered Oct 15 '22 03:10

spender


As pointed out, it won't wait until the request is done. Here's a way to interval a promise:

 function checkQueue(url, cb) {
     var xhr = new XMLHttpRequest();
     xhr.addEventListener("loadend", cb);
      xhr.addEventListener("load", reqListener);
     xhr.open('GET', url, true);
     xhr.send();
 }

function reqListener ()
{
    var queue = JSON.parse(this.responseText);
    notifyAllPorts(queue);
    console.log(this.responseText);
}

 var promise = Promise.resolve(true);

 setInterval(function () {
     promise = promise.then(function () {
         return new Promise(function (resolve) {
             checkQueue(yourUrlHere, resolve);
         });
     });
 }, 1000);

It will keep on adding requests to do every second, but it will delay itself if it goes over 1 second.

like image 25
MinusFour Avatar answered Oct 15 '22 03:10

MinusFour


setInterval simply queues the code to run once the current call stack is finished executing. This can be useful for some things.

So yes, it's asynchronous in that it breaks the synchronous flow, but it's not actually going to execute concurrently/on a separate thread. If your goal is background processing, have a look at webworkers.

So regardless of how much time server takes it will request every second as per your code is set for 1000

like image 21
sumeet kumar Avatar answered Oct 15 '22 01:10

sumeet kumar