【发布时间】:2017-03-03 16:57:39
【问题描述】:
在 Node.js 中,我需要读取一个文件并验证它的内容,所有这些都是异步的。我正在使用 Node.js 6.6、bluebird 3.4.6
示例代码:
// pseudo function to read file contents - resolves when 'flag' is true, rejects when 'flag' is false.
function readFile(flag) {
return new Promise(function (resolve, reject) {
console.log('Reading file...');
if (flag) {
resolve('File contents');
} else {
reject('readFile error');
}
});
}
// pseudo function to validate file contents - resolves when 'flag' is true, rejects when 'flag' is false.
function validate(fileContents, flag) {
return new Promise(function (resolve, reject) {
console.log('Validating file: ', fileContents);
if (flag) {
resolve('Validate passed');
} else {
reject('validation failed');
}
});
}
readFile(false)
.then(function (fileContents) {
console.log('Successfully read the file:', fileContents);
return fileContents;
})
.catch(function (fileReadErr) {
console.log('Failed to read the file:', fileReadErr);
throw fileReadErr; // or, return Promise.reject(err);
})
.then(function (fileContents) {
return validate(fileContents, false);
})
.then(function (result) {
console.log('Successfully validated the file:', result);
})
.catch(function (err) {
console.log('Failed to validate the file:', err);
})
;
<script src="https://cdn.jsdelivr.net/bluebird/3.4.6/bluebird.min.js"></script>
上面的代码会打印出来
Reading file...
Failed to read the file: readFile error
Failed to validate the file: readFile error
上面的promise链大致翻译成下面的同步代码:
try {
let fileContents;
try {
fileContents = readFile(false);
console.log('Successfully read the file:', fileContents);
} catch (e) {
console.log('Failed to read the file:', e);
throw e;
}
let validationResult = validate(fileContents, false);
console.log('Successfully validated the file:', validationResult);
} catch (err) {
console.log('Failed to validate the file:', err);
}
并且,在第一个 catch 方法中抛出或拒绝 仍将调用第二个 catch 方法。
我的问题:一旦文件读取失败,有什么办法可以断链吗?我的目标是从 express.js 路由返回不同的 HTTP 状态代码(文件读取错误:500,验证失败:400)。
我知道使用非标准专用 catch 方法的解决方案,但这需要特殊处理。从某种意义上说,我需要在错误对象中抛出错误或需要一些过滤键,而这两者都不在我手中,并且需要一些工作来实现它。此解决方案在 bluebird docs 和此处提到:Handling multiple catches in promise chain
【问题讨论】:
-
对于那些想要将其标记为 stackoverflow.com/questions/26076511/… 的副本的人,我想知道任何其他可能的解决方案,同样我不想在一个
catch中处理所有错误@Esailija(蓝鸟作者)在这里提到的链的末端stackoverflow.com/a/26077569/340290 -
鉴于您的问题的限制,答案可能是“不,没有办法打破捕获链”。在链的末端使用 final catch 处理程序有什么反对意见?
-
要在最后使用
catch,至少我需要维护一个标志或者必须验证错误对象才能知道不同的错误状态。它会变成 if-elseif-else 类型。不是吗? -
正确。另一种选择是使用 Babel 和
async/await或像 co 这样的异步生成器库 -
是的,这就是我目前正在查看的内容。我或多或少需要这个功能:caolan.github.io/async/docs.html#series