Qudusayo
Qudusayo

Reputation: 1159

Watch an API for Updates

I am trying to make an API watch to https://api.exchangeratesapi.io/latest and detect if any changes so I can update my clients just like a web hook notification. But what am doing is

while(true){
    fetch(https://api.exchangeratesapi.io/latest)
    .then(res => ......
}

I am caching the result and always check if there is any changes, If there is, I will send a request to the client.
I am looking for a better way to pull the data instead of making a while loops

Upvotes: 0

Views: 941

Answers (1)

VLAZ
VLAZ

Reputation: 29004

If you use a while loop, you would potentially send many requests before one returns. And even when one returns, it's not going to necessarily be in order. Here is a quick example of what might happen if there is a network spike for example:

const sleep = ms => new Promise(res => setTimeout(res,  ms));

async function mockNetworkCall(num) { 
  const timings = [50, 150, 50]
  console.log(`sending request ${num}`);
  await sleep(timings[num]);
  
  console.log(`request ${num} finished`)
}


for(let i = 0; i < 3; i++) {
  mockNetworkCall(i);
}

You could avoid the while loop if you instead take the approach to only do a new request when the last one finishes. In that case, you will only have a single request active at any one time and you know that you're getting the result in order.

You can wrap the logic for that in a simple function to watch a URL and only re-initiate a request when the previous one is finished. This is the skeleton for such a function - it might need tweaking according to your needs:

function watch({ url, retryCount, lastResponse = null}) {
  fetch(url)
    .then(res => { 
      
      /* do something */
      
      return res;
    })
    .then(res => watch({url, retryCount, lastResponse: res})) //launch again
    .catch(err => { 
      /* handle error */ 
      console.error("error getting URL", err);
      console.warn("retries left: ", retryCount);
      
      if (retryCount-- > 0) {
        watch({url, retryCount, lastResponse});
      }
    })
}

watch({url: "google.com", retryCount: 3});

Or the same using async/await

async function watch({ url, retryCount, lastResponse = null}) {
  try {
    const res = await fetch(url);

    /* do something */
    
    watch({url, retryCount, lastResponse: res}); //launch again
  } catch (err) {
    /* handle error */ 
    console.error("error getting URL", err);
    console.warn("retries left: ", retryCount);
      
    if (retryCount-- > 0) {
      watch({url, retryCount, lastResponse});
    }
  }
}

watch({url: "google.com", retryCount: 3});

Upvotes: 3

Related Questions