Zeppe
Zeppe

Reputation: 83

How to break chain in promise

I'm trying to limit the number of apis fetches in my project by saving them in a simple cache, key collection in mongodb. Is thera way to stop propagation of .then() inside Promise, without using async/await?

export const getData = (url: string) => {
    return new Promise((resolve, reject) => {
        findInCache(url)
            .then((cached: string | null) => {
                if (cached) {
                    resolve(cached);
                }
            })
            .then(() => {
                axios
                    .get(url)
                    .then(({data}) => {
                        setCache(url, data, TTL);
                        resolve(data);
                    })
                    .catch(e => reject(e));
            });
    });
};

Upvotes: 0

Views: 65

Answers (3)

Jaromanda X
Jaromanda X

Reputation: 1

Firstly, lets get rid of the Promise constructor anti-pattern - your function call inside the promise executor returns a promise, so, no need for anew Promise

Secondly, only run the second request if the result of the first is empty

export const getData = (url) => findInCache(url)
// here we return haveResult and avoid axios.get(url) altogether
.then((haveResult) => haveResult || axios.get(url)
    // sometimes nested .then is useful like in this case
    .then(({data}) => {
        setCache(url, data, TTL);
        return data;
    })
);

Upvotes: 4

Alex
Alex

Reputation: 1423

When you return something result in then, this result is come into next then function. So, you can control what you would do in next then based on input parameter inCache. So you can do something like:

export const getData = (url: string) => {
    return new Promise((resolve, reject) => {
        findInCache(url)
            .then((cached: string | null) => {
                if (cached) {
                    resolve(cached);
                    return true;
                }
                return false;
            })
            .then((inCache) => {
                if (!inCache) {
                  axios
                      .get(url)
                      .then(({data}) => {
                          setCache(url, data, TTL);
                          resolve(data);
                      })
                      .catch(e => reject(e));
               }
            });
    });
};

Upvotes: 0

Raj Nandan Sharma
Raj Nandan Sharma

Reputation: 3862

you can just do this instead instead of chaining. if it is in cache then fetch from cache else get from url

export const getData = (url: string) => {
    return new Promise((resolve, reject) => {
        findInCache(url)
            .then((cached: string | null) => {
                if (cached) {
                    resolve(cached);
                } else {
                  axios
                    .get(url)
                    .then(({data}) => {
                        setCache(url, data, TTL);
                        resolve(data);
                    })
                    .catch(e => reject(e));
                  }
            })

    });
};

Upvotes: 0

Related Questions