从失败的承诺中 'recover' 的正确方法?

Proper way to 'recover' from a failed promise?

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

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

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

问题的症结在于,只要 if 语句进入 else 块,或者当 promise 进入 catch 块时,我都需要执行 doThisInstead() 或任何函数/内联代码,并且在这种特殊情况下,我无法知道承诺会在尝试之前进入 catch 块。

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

如果你使用 _async / await _ 语法,你可以等待 doPromise(),然后 运行 doThisInstead() 如果 something 是假的或发生错误,这意味着在您的代码中只调用一次 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()

您可能正在寻找 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();
}

这可以通过 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();