问题描述
我对 JS 开发还很陌生,我最近发现了 DRY(不要重复自己)的概念,它帮助我清理了很多代码。
我在整个项目的几个地方都遇到了以下类型的问题,我正在努力想办法改进它,同时保持可读性和不重复代码的原则。
const Helpers = use('Helpers')
Route.post('upload',async ({ request }) => {
const profileFile = request.file('filetoUpload',{
types: ['pdf'],size: '20mb'
})
await profileFile.move(Helpers.tmpPath('uploads'),{
name: '',overwrite: true
})
if (!profileFile.moved()) {
return profileFile.error()
}
return 'File moved'
})
关键是我需要执行 doThisInstead() 或任何函数/内联代码,无论何时 if 语句进入 else 块,或者当 promise 进入 catch 块时,在这个在特定情况下,我无法知道承诺会在尝试之前进入 catch 块。
编写这样的代码很快就会变得一团糟,所以我很感激任何提示。非常感谢!
解决方法
您可能正在寻找 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();
}
,
如果您使用 _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()
这可以通过 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();