Tom*_*ski 6 javascript asynchronous node.js express
节点 8.1.2,我有一个结构,其中一个文件在映射中调用另一个文件的函数。在一个真实的例子中,我会使用Promise.all
,map
但这不是这里的问题。这是结构:
A.js:
const { b } = require('./B')
function expressStuff (req, res, next) {
things.map(thing => {
return b(thing)
}))
return res.status(200).json(...)
}
Run Code Online (Sandbox Code Playgroud)
B.js:
// Thing -> Promise<Object>
function b (thing) {
return ThingModel.update(...) // this returns a Promise but FAILS and throws an errror
}
module.exports = { b }
Run Code Online (Sandbox Code Playgroud)
好的。所以在函数中,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(...)
}
Run Code Online (Sandbox Code Playgroud)
但这仍然没有被抓住。
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(...)
}
Run Code Online (Sandbox Code Playgroud)
还是没处理好。我尝试使用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(...)
}
Run Code Online (Sandbox Code Playgroud)
当您承诺时,使用try
/处理拒绝catch
仅在async function
s 中有效await
- 您还没有尝试过。
你可以这样做
async function expressStuff (req, res, next) {
var results;
try {
results = await Promise.all(things.map(b)); // throws when any of the promises reject
} catch (err) {
return next(err) // handle error
}
return res.status(200).json(...)
}
Run Code Online (Sandbox Code Playgroud)
或者(比如等到所有 ES6 承诺完成,甚至拒绝承诺)
function expressStuff (req, res, next) {
const resultPromises = things.map(async (thing) => {
try {
return await b(thing); // throws when the promise for this particular thing rejects
} catch (err) {
return defaultValue; // handle error - don't call `next` here
}
});
…
return res.status(200).json(...)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3961 次 |
最近记录: |