【问题标题】:Proper way to 'recover' from a failed promise?从失败的承诺中“恢复”的正确方法?
【发布时间】:2021-02-08 11:00:47
【问题描述】:

我是 JS 开发的新手,我最近发现了 DRY(不要重复自己)的概念,它帮助我清理了很多代码。

我在整个项目中的几个地方都遇到了以下类型的问题,我正在努力想一种方法来改进它,同时保持可读性和不重复代码的原则。

    if (something) {
        doPromise().then(() => {
            doSomething()
        }).catch(e => {
            doThisInstead()
        })
    } else {
        doThisInstead()
    }

关键是我需要执行 doThisInstead() 或任何函数/内联代码,只要 if 语句进入 else 块,或者当 promise 进入 catch 块时,并且在这个在特定情况下,我无法知道承诺会在尝试之前进入 catch 块。

编写这样的代码很快就会变得混乱,所以我会很感激任何提示。非常感谢!

【问题讨论】:

  • 但是如果 promise 到了 catch 就意味着有些事情是真的,因为否则你不会进入 if 并且如果 someting 是假的,你就会去 else。你到底想优化什么?
  • 我想避免 doThisInstead() (或其他任何东西)基本上两次,但是当某些事情是错误的并且承诺进入 catch 块时我采取的行动是相同的
  • 是一样的,但是没办法同时触发,所以没关系

标签: javascript node.js promise coding-style


【解决方案1】:

您可能正在寻找if-else flow in promise (bluebird),只需使用catch 而不是then

(something
  ? doPromise().then(() => {
      doSomething()
    })
  : Promise.reject()
).catch(e => {
    doThisInstead()
})

async/await写的,应该是

try {
    if (!something)
        throw new Error("something is wrong")
    await doPromise();
    await doSomething();
} catch(e) {
    await doThisInstead();
}

不那么依赖异常的替代方法是

if (!something || await doPromise().then(doSomething).then(() => false, () => true)) {
    doThisInstead();
}

【讨论】:

  • 您能否解释一下您发布的第三个选项中发生了什么,特别是第二个选项?谢谢
  • @kougami 基本上这是特里在下面使用errorOccurred 所做的,只是使用了承诺风格。你可能想看看how .then(…, …) works
【解决方案2】:

如果您使用 _async / await _ 语法,您可以等待 doPromise(),然后如果 something 为假或发生错误,则运行 doThisInstead(),这意味着只调用一次 doThisInstead( ) 在您的代码中。

此示例将导致 doPromise() 50% 的时间失败。

let something = true;

// Fail 50% of the time
function doPromise() {
    return new Promise((resolve, reject) => setTimeout(Math.random() <= 0.5 ? resolve: () => reject(new Error("Some error")), 100));
}

function doSomething() {
    console.log("doSomething()");
}

function doThisInstead() {
    console.log("doThisInstead()");
}

async function test() {
    errorOccurred = false;
    if (something) {
        try {
            await doPromise();
            doSomething();
        } catch (e) {
            errorOccurred = true;
        }
        console.log("doPromise: " + (errorOccurred ? "error occurred." : "ran successfully"));
    }
    
    // Run doThisInstead() if either an error occurred or something is falsey
    if (!something || errorOccurred) {
        doThisInstead();
    }
}

test()

【讨论】:

    【解决方案3】:

    这可以通过 Promise 解决,使用以下代码:

    function hypotheticalFunction() {
        const doSomething = () => {
            // stuff
        }
        const doThisInstead = () => {
            // stuff
        }
        const doSomethingHandler = () => {
            return new Promise((resolve,reject) => { 
                if (something) {
                    doPromise().then(() => {
                        doSomething();
                        resolve();
                    }).catch(() => {
                        reject();
                    })
                } else {
                    reject();
                }
            })
        }
        doSomethingHandler().catch(doThisInstead);
    }
    hypotheticalFunction();
    

    【讨论】:

      猜你喜欢
      • 2017-10-09
      • 1970-01-01
      • 2014-08-19
      • 2018-05-08
      • 2020-08-09
      • 2015-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多