【发布时间】:2017-12-15 03:43:51
【问题描述】:
节点 8.1.2,我有一个结构,其中一个文件在映射中调用另一个文件的函数。在一个真实的例子中,我会在map 上使用Promise.all,但这不是这里的问题。这是结构:
A.js:
const { b } = require('./B')
function expressStuff (req, res, next) {
things.map(thing => {
return b(thing)
}))
return res.status(200).json(...)
}
B.js:
// Thing -> Promise<Object>
function b (thing) {
return ThingModel.update(...) // this returns a Promise but FAILS and throws an errror
}
module.exports = { b }
好的。所以在函数b 中,我尝试获取一些异步数据(来自数据库)。它失败并抛出 Uncaught Promise Rejection。
如何处理?
我尝试了多种解决方案:
A1.js:
const { b } = require('./B')
function expressStuff (req, res, next) {
things.map(thing => {
try {
return b(thing)
} catch (err) {
return next(err)
}
}))
return res.status(200).json(...)
}
但这仍然没有被抓住。
A2.js:
const { b } = require('./B')
function expressStuff (req, res, next) {
try {
things.map(thing => {
return b(thing)
}))
} catch (err) {
return next(err)
}
return res.status(200).json(...)
}
仍未处理。我尝试使用Promise.all,我尝试了双重try-catch 块(因为我认为map 内部的那个可能会从next 返回到map 结果,而不是实际上来自expressStuff 函数。仍然没有。
我得到答案的最后是处理错误,但代码不会等待它被抛出,res.status() 和 next 都可以工作,导致竞争条件和 cannot set headers after they are sent 错误。
我想做的只是让函数b 抛出一个错误,但在expressStuff 中捕获它,这样我就可以重新抛出自定义UnprocessableEntityError 并将其传递给next。似乎来自文件 B 的错误没有冒泡到调用它的 map。
我该怎么做?
编辑:
我可以处理此拒绝的唯一方法是尝试在B.js 中捕获它。但是,如果我尝试重新抛出错误/返回它 - 什么都没有。错误被吞没。如果我尝试console.log 它 - 它会被记录下来。
详情:
感谢标记的答案,我重构了我的实际代码并使其完美运行。
function expressStuff (res, req, next) {
try {
await Promise.all(things.map(async thing => {
if (ifSomething()) {
await b(thing)
}
}))
} catch (err) {
return next(new MyCustomError('My Custom Error Message'))
}
return res.status(200).json(...)
}
【问题讨论】:
标签: javascript node.js express asynchronous