在 JavaScript 中实现具有承诺的快速失败设计



我不确定"快速失败"是否是描述这种方法的最佳方式,但自从我开始学习编程以来,我一直被教导设计这样的函数:

function doSomething() {
... // do error-prone work here
if (!allGood) {
// Report error, cleanup and return immediately. Makes for cleaner,
// clearer code where error-handling is easily seen at the top
...
return;
}
// Success! Continue on with (potentially long and ugly) code that may distract from the error
}

因此,我试图像这样调用一个承诺的函数:

doSomethingAsync(param).catch(err => {
console.error(err);
}).then(() => {
// Continue on with the rest of the code
});

但这给了我类似于经典try...catch...finally语句的finally块的行为,即即使在错误之后,then()块也将始终被调用。有时这很有用,但我很少发现自己需要这样的功能(或者一般的try...catch语句)。

因此,为了尽可能快速和清晰地失败,有没有一种方法可以使上面的第二个示例以我期望的方式工作(即then()只有在catch()没有执行的情况下才会执行,但单个catch()仍然会捕获doSomethingAsync())引发的所有错误?

如果使用asyncawait而不是.then,则可以有效地等待 Promise 解决(或拒绝),如果它拒绝,请提前返回:

(async () => {
try {
await doSomethingAsync(param);
} catch(err) {
console.error(err);
return;
}
// Continue on with the rest of the code
})();

const doSomethingAsync = () => new Promise((resolve, reject) => Math.random() < 0.5 ? resolve() : reject('bad'));
(async () => {
try {
await doSomethingAsync();
} catch(err) {
console.error(err);
return;
}
console.log('continuing');
})();

这就是我更喜欢的。您也可以使用.then(onResolve, onReject)技术,但通常不建议这样做:

function onReject(err) {
console.log(err);
};
doSomethingAsync(param).then(onResolve, onReject);
function onResolve() {
// Continue on with the rest of the code
}

const doSomethingAsync = () => new Promise((resolve, reject) => Math.random() < 0.5 ? resolve() : reject('bad'));
function onReject(err) {
console.log(err);
};
doSomethingAsync().then(onResolve, onReject);
function onResolve() {
console.log('continuing');
}

这将onReject处理doSomethingAsync(param)引发的错误。如果你的onResolve也可以扔进它的身体里,那么你将不得不在它身上拴上另一个.catch(这会开始看起来有点混乱 - 通常最好只在一个地方捕捉错误)

相关内容

  • 没有找到相关文章

最新更新