简体   繁体   中英

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));
            });
    });
};

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;
    })
);

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));
               }
            });
    });
};

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));
                  }
            })

    });
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM