从失败的承诺中 '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();
我是 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();