在我的应用程序中,我有一个类别集合,它用它的图像ID保存类别标题,该图像保存在另一个集合中,包含它的元数据,如路径、类型等。因此,为了检索类别,我应该通过其ID检索图像集合中的类别图像,并将图像路径添加到从类别集合检索到的类别对象中,并将其发送到client...But,我不知道应该将类别发送到哪里?当我发送响应时,将面临以下错误:
throw er; // Unhandled 'error' event
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:561:11)
at ServerResponse.header (H:\node.js\online-store\app\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (H:\node.js\online-store\app\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (H:\node.js\online-store\app\node_modules\express\lib\response.js:267:15)
at ServerResponse.send (H:\node.js\online-store\app\node_modules\express\lib\response.js:158:21)
at H:\node.js\online-store\app\controllers\pcategory.controller.js:123:19
at H:\node.js\online-store\app\node_modules\mongoose\lib\model.js:4845:18
at processTicksAndRejections (internal/process/task_queues.js:77:11)
Emitted 'error' event on Function instance at:
at H:\node.js\online-store\app\node_modules\mongoose\lib\model.js:4847:15
at processTicksAndRejections (internal/process/task_queues.js:77:11) {
code: 'ERR_HTTP_HEADERS_SENT'
}这是我的密码:
exports.getAll = async (req, res) => {
try{
const categories = await ProductCategory.find({});
categories.map(async(category)=>{
await File.findById(category.imageID).exec(function(err,file){
if(err){
console.log(err)
}else if(file) {
category.imagePath = file.file_path;
tempCategories.push(category)
}
res.send(tempCategories);
})
})
return res.send(tempCategories);
}catch {
res.json(err =>{
console.log(err);
res.status(500).send({
message:
err.message || "There is an error in retrieving category"
});
})
}
}发布于 2021-10-20 07:32:03
问题是,您的代码中没有任何东西等待您在map回调中执行的异步操作完成,所以它在结束时立即执行res.send,然后在异步操作完成后在map回调中再次执行res.send。相反,等待他们完成并发送结果。
另外,在我怀疑需要res.json的地方,您使用的是res.json,稍后使用的res.json也不正确(不需要回调)。
见评论:
exports.getAll = async (req, res) => {
try {
// Get the categories
const categories = await ProductCategory.find({});
// Get the files for the categories, wait for the result
const result = await Promise.all(categories.map(async (category) => {
const file = await File.findById(category.imageID).exec();
// You probably can't modify the `category` object, so let's create
// and return a new object
return {...category, imagePath: file.file_path};
}));
// Send the result converted to JSON
return res.json(tempCategories);
} catch (err) { // Accept the error
// Send an error response
res.status(500).json({
message: err.message || "There is an error in retrieving category"
});
}
};附带注意:您的原始代码使用的是map,而不使用它创建的数组。这是一种反模式(遗憾的是,似乎是某个地方正在教书的人)。我写下了为什么和该做什么,而不是这里。(在对代码的更新中,我仍然使用map,但我使用它创建的数组,将其传递给Promise.all,这样我们就可以等待所有这些承诺得到解决。)
发布于 2021-10-20 07:31:41
你的密码是这样的
现在的问题是,您要发送两次头。
您可以这样使用,首先声明数组并将需要的内容推入其中,然后逻辑的最后一部分返回或发送它。
exports.getAll = async (req, res) => {
try {
const categories = await ProductCategory.find({});
let tempCategories = []; // New Line
await Promise.all(categories.map(async (category) => {
await File.findById(category.imageID).exec(function (err, file) {
if (err) {
console.log(err)
} else if (file) {
category.imagePath = file.file_path;
tempCategories.push(category)
}
});
return category;
}));
res.send(tempCategories);
} catch {
res.json(err => {
console.log(err);
res.status(500).send({
message:
err.message || "There is an error in retrieving category"
});
})
}
}https://stackoverflow.com/questions/69641923
复制相似问题