1
export function getDeferred () {
    let resolve; let reject;
    const promise = new Promise((res, rej) => {
        resolve = res;
        reject = rej;
    });

    promise.resolve = resolve;
    promise.reject = reject;
    return promise ;
};


let deferred=getDeferred();

async function fetchSomeData(){
    let data=await fetch('...')
    deferred.resolve(data);
}

async function someFunctionMustHaveFetchedData(){
    let data = await deferred;
    // do something after deferred resolved
}



why am i doing this?
someFunctionMustHaveFetchData will be called many times but data should only be fetch once

moonkop
  • 29
  • 2
  • As Felix said, it is an anti-pattern to do it this way when you don't have to. There are certain instances where the use of a Deferred object that externally exposes resolve/reject handlers is a simpler way to implement something (I've personally only encounted it a couple times in the last 5 years), so it seems to me a pretty rare circumstance. I just discussed a case of whether you need a Deferred or not here [Can you write this without using a deferred?](https://stackoverflow.com/questions/61358448/can-you-write-this-without-using-a-deferred). – jfriend00 Apr 27 '20 at 09:34
  • "anti-pattern" is the secret signal for "experts only" ... if you use it, you must be really sure what you're doing, or you are definetly doing something wrong. In your case, your usage looks good, so ... – Jonas Wilms Apr 27 '20 at 13:02
  • @JonasWilms No. This one really is an antipattern. Experts sometimes do use something similar, where they store the `resolve` function on some object together with the promise, but they never store it on the promise itself. – Bergi Apr 27 '20 at 14:08

1 Answers1

1

It's probably not an "anti-pattern" per se, but I would only expose reject and resolve if you absolutely have to. Which is not the case here. You can just store the promise or the data in a variable:

let promise;

async function someFunctionMustHaveFetchedData(){
    if (!promise) {
      promise = fetch('...');
    }
    let data = await promise;
    // do something after deferred resolved
}
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143