8

I have a function that is dependent on a Promise being resolved from an async action (API fetch).

The async action needs to either return the Fetch promise, or return a promise that resolves when the Fetch completes.

However, the Fetch should only happen once.

I could store the fetch promise in a global variable, and return that, but is that an anti-pattern in Redux? Should the Promise be in the Redux store, since it's part of the application state?

Example code:

//Should this be in Redux Store?
var promise = null;

myfunction() {
  doAsyncTask().then(() => {
    //Continue
  });
}

doAsyncTask() {
  if(promise === null) {
    promise = fetch('URI');
  }
  return promise;
}
David
  • 81
  • 5
  • you don't need to know. cache the promise the first time the function is called, and always return that cached promise. btw. why do you need that delayed call to `fetch('URI')` *(doAsyncTask())*? why don't you call it in the first place, save the promise and use it instead of calling doAsyncTask()? – Thomas Aug 25 '16 at 13:50
  • Thanks for your reply, the isFetching flag is in the Redux Store, would you store the Promise in there too? – David Aug 25 '16 at 13:56
  • don't know I have pretty much no experience with redux. To mind are coming two questions: what kind of store is it? can it handle a promise, or does it need serializable data? and the second thought: how long do you need that promise? is that the right place to store data for that duration? like for example, if it is a global store, and you need that promise only for one module, there might be a better place to store it. But as mentioned, there are devs here with more experience in redux to provide you a proper answer to this question. – Thomas Aug 25 '16 at 14:04
  • It's an object store, so I presume it can store a promise. I agree with your point about the duration, and that's why I'm hesitant to store it in Redux. However, it's part of the application state, and feels like an Anti-Pattern to have state outside the store. To answer your previous comment, the call is delayed to prevent polluting myFunction as the Fetched data has to be processed etc. Thanks – David Aug 25 '16 at 14:10
  • Are you using the async fetch for updating the store? In other words, are you using a `thunk` ? – anoop Aug 25 '16 at 14:21
  • Yes async fetch should update the store with the response from the API, and uses thunk. – David Aug 25 '16 at 14:40
  • 2
    The question is similar to http://stackoverflow.com/a/18745499/6757219 But the real question is where to store 'dataPromise' in the context of a Redux State Container. – David Aug 25 '16 at 15:02

1 Answers1

0

This is a simple method for caching a promise, or basically any computation a function produces, so when the function is called again (after the first time) it will return the last computed value, which in the below case is always the **same* promise (either resolved or pending).

For your specific needs you can replace the Promise with a fetch and store it in the cache variable.

function myfunction(){
  doAsyncTask().then(RES => {
    console.log(RES);
  });
}

const doAsyncTask = (cache => {
  return function(){
    // when called first time, put the promise in the "cache" variable
    if( !cache ){
        cache = new Promise(function(resolve, reject){
            setTimeout(() => {
                resolve('foo');
            }, 2000);
        });
    }
    return cache;
  }
})();

myfunction(); 
myfunction(); // second call uses the exact same promise
vsync
  • 118,978
  • 58
  • 307
  • 400