【问题标题】:How to break chain in promise如何打破承诺的链条
【发布时间】:2019-03-21 09:04:56
【问题描述】:

我试图通过将它们保存在一个简单的缓存中来限制我项目中的 api 获取数量,即 mongodb 中的密钥集合。有没有办法在不使用 async/await 的情况下停止 Promise 中 .then() 的传播?

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

【问题讨论】:

  • 在 Promise 执行器中包含 .then 表明您对承诺构造函数反模式有罪
  • @Liam Wound 没有调用拒绝导致在我调用 getData() 的地方触发 .catch ?

标签: javascript express asynchronous es6-promise


【解决方案1】:

首先,让我们摆脱 Promise 构造函数的反模式 - 你在 Promise 执行器中的函数调用返回一个 Promise,因此,不需要新的 Promise

其次,如果第一个请求的结果为空,则只运行第二个请求

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

【讨论】:

    【解决方案2】:

    你可以这样做而不是链接。如果它在缓存中,则从缓存中获取,否则从 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));
                      }
                })
    
        });
    };
    

    【讨论】:

    • 这需要更多解释
    • 在 Promise 执行器中包含 .then 表明您对承诺构造函数反模式有罪
    • 我试图避免在代码中缩进太多。 :/ 我最初认为调用 resolve() 会终止 Promise 中的其余代码。
    【解决方案3】:

    当您在then 返回某些结果时,此结果将进入下一个then 函数。因此,您可以根据输入参数inCache 控制下一个then 中要执行的操作。所以你可以这样做:

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

    【讨论】:

    • 这需要更多解释
    • 在答案中添加更新
    • 在 Promise 执行器中包含 .then 表明您对 Promise 构造函数反模式有罪
    猜你喜欢
    • 2017-11-23
    • 2020-02-23
    • 2015-06-12
    • 2015-08-21
    • 2016-09-03
    • 2019-05-10
    相关资源
    最近更新 更多