Real time using polling

How to implement polling in javascript?

In this article we are going to learn about how to achieve real time in our web application. There are multiple ways to achieve real time. One of the way is using polling method. Polling is just a fancy term where we continuously make api calls to get updated result. We will go through how to achieve this in Javascript.

We can achieve polling using two ways in javascript.

  • setTimeout

  • requestAnimationFrame

First We will se how to achieve polling using setTimeout

Using setTimeout

let allChat = [];
const INTERVAL = 3000;

async function getNewApiCall() {
  let json;
  try {
    const res = await fetch("/API_END_POINT");
    json = await res.json();
  } catch (e) {
    console.error("polling error", e);
  }
  allChat = json.msg;
  setTimeout(getNewApiCall, INTERVAL);
}

getNewApiCall();

Here in the above function we can put any api endpoint instead of /API_END_POINT. In this approach there are two major problems.

  • If user left the tab open still it will keep on making api call which is not right for our server.

  • Even if the api give us error still this function will continue to make api call.

To tackle this first problem we are going to use requestAnimationFrame which will pause the the function when user switches the tab or when the tab is not in focus.


const INTERVAL = 3000;

let nextRequest= 0;

async function getNewApiCall() {
  let json;
  try {
    const res = await fetch("/API_END_POINT");
    json = await res.json();
  } catch (e) {
    console.error("polling error", e);
  }
  allChat = json.msg;
  render();
}


function timer(time) {
  if (nextRequest <= time) {
    getNewApiCall();
     nextRequest = time + INTERVAL;
  }
  requestAnimationFrame(timer);
}

requestAnimationFrame(timer);

Here we have used the requestAnimationFrame to pause the api call when tab is not in focus. We are making the api calls after every 3s. But still we have a problem what if our api fails for some reason we don't want to make api calls at the same frequency. To address this issue we will use backoff. What we will do is if our api fails we will make next request after some delay. We will handle that in next section.


const INTERVAL = 3000;

async function getNewApiCall() {
  try {
    const res = await fetch("/API_END_POINTS");
    const json = await res.json();

    if (res.status >= 400) {
      throw new Error("request did not succeed: " + res.status);
    }

    allChat = json.msg;
    render();
    failedTries = 0;
  } catch (e) {
    // back off
    failedTries++;
  }
}


const BACKOFF = 5000;
let timeToMakeNextRequest = 0;
let failedTries = 0;
async function Timer(time) {
  if (timeToMakeNextRequest <= time) {
    await getNewApiCall();
    timeToMakeNextRequest = time + INTERVAL + failedTries * BACKOFF;
  }
  requestAnimationFrame(Timer);
}

requestAnimationFrame(Timer);

Here in the above code you can see inside the catch block we are increasing the failedTries inside the Timer function we updating the timeToMakeNextRequest value failedTries * BACKOFF which is a linear backoff. In linear backoff then once our api fails next request we will make after 5s. In above code we have used linear. we can also using exponential backoff.

That's all we need to do to create a production ready polling function. I hope you get to learn something new. If you like this article give a thumbs up.

To explore more such tutorial visit.

Did you find this article valuable?

Support aditya kumar by becoming a sponsor. Any amount is appreciated!