skip to Main Content

I have this code to get some data from an API:

const data = async () => {
  const apiResponse = await dataFromAPI();
  return apiResponse;
}

The apiResponse will always be the same for a session where this code is run. I chose this design because I would like the opportunity to chain multiple functions to the API.

I added a cache variable to short-circuit future requests.

let dataCache;

const data = async () => {
  if (dataCache) return dataCache;
  const apiResponse = await dataFromAPI();
  dataCache = apiResponse;
  return dataCache;
}

However, calling data() twice in succession will make still two API requests.

data().then(response => console.log(response))
data().then(response => console.log(response))

This makes one API request, then uses the cache variable:

data().then(response => console.log(response))
setTimeout(() => {
  data().then(response => console.log(response))
}, 100)

How can I design a singleton for this?

2

Answers


  1. I think you can work with the Promise as the thing you cache like this:

    let dataCache;
    
    const data = async () => {
      if (!dataCache) {
          dataCache = dataFromApi();
      }
      return await dataCache;
    }
    

    That way dataCache will be set to the Promise returned from the API call. If it’s set, then it will be resolved already or it won’t be; in either case, a second API call won’t be made.

    Login or Signup to reply.
  2. Pointy’s answer is classical, you can even optionally wrap everything inside an iife or so. If you want something else to experiment with you can try async generators:

    async function* data() {
        const res = await dataFromAPI();
        while(true){
            yield res
        }
    }
    
    let myData = data();
    myData.next() //Promise with res
    myData.next() //Different Promise with same res
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search