在 JavaScript 中实现带有承诺的快速失败设计
Implementing a fail-fast design with promises in JavaScript
我不确定 "fail-fast" 是否是描述这种方法的最佳方式,但自从我开始学习编程以来,我一直被教导这样设计函数:
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
}
因此,我正在尝试像这样调用一个 promisified 函数:
doSomethingAsync(param).catch(err => {
console.error(err);
}).then(() => {
// Continue on with the rest of the code
});
但这给了我类似于经典 try...catch...finally
语句的 finally
块的行为,即 then()
块将 always被调用,即使在错误之后。有时这很有用,但我很少发现自己需要这样的功能(或一般的 try...catch
语句,就此而言)。
所以为了尽可能快速和清楚地失败,有没有一种方法可以让上面的第二个例子以我期望的方式工作(即 then()
仅在 catch()
不是,但是单个 catch()
仍然会捕获 doSomethingAsync()
)?
引发的所有错误
如果你使用 async
和 await
而不是 .then
,你可以有效地等待 Promise 解决(或拒绝),如果它拒绝,return早:
(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)
技术,尽管它是 usually not recommended:
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
链接到它上面(这会开始看起来有点乱 - 通常最好只在一个地方捕获错误)
我不确定 "fail-fast" 是否是描述这种方法的最佳方式,但自从我开始学习编程以来,我一直被教导这样设计函数:
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
}
因此,我正在尝试像这样调用一个 promisified 函数:
doSomethingAsync(param).catch(err => {
console.error(err);
}).then(() => {
// Continue on with the rest of the code
});
但这给了我类似于经典 try...catch...finally
语句的 finally
块的行为,即 then()
块将 always被调用,即使在错误之后。有时这很有用,但我很少发现自己需要这样的功能(或一般的 try...catch
语句,就此而言)。
所以为了尽可能快速和清楚地失败,有没有一种方法可以让上面的第二个例子以我期望的方式工作(即 then()
仅在 catch()
不是,但是单个 catch()
仍然会捕获 doSomethingAsync()
)?
如果你使用 async
和 await
而不是 .then
,你可以有效地等待 Promise 解决(或拒绝),如果它拒绝,return早:
(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)
技术,尽管它是 usually not recommended:
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
链接到它上面(这会开始看起来有点乱 - 通常最好只在一个地方捕获错误)