需要帮助来理解如何解决嵌套在多个猫鼬查询和映射数组中的承诺
Need help to understand how to resolve a promise that is nested within multiple mongoose queries and a mapped array
router.get('/pictures', (req, res, next) => {
Picture.find()
.then(handle404)
.then(pictures => {
return pictures.map(picture => picture.toObject())
})
.then(pictures => {
pictures.map(picture => {
User.findById(picture.owner)
.then(owner => {
picture.ownerName = owner.username
console.log(pictures, "my picture with owner")
return pictures
})
.then(pictures => res.status(200).json({ pictures: pictures }))
})
})
.catch(next)
})
})
操作顺序:我需要找到所有图片,然后遍历图片数组并找到所有者的用户名,然后在图片数组中添加所有者用户名的键,然后发送响应包含所有者用户名的新图片数组
我想 return 包含找到的所有者名称的图片数组。但是我在设置所有者名称之前发送响应时遇到问题,我不确定如何获得响应等待。如果只有一个所有者的名字没问题,但如果超过一个,我会得到一个错误 -
UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
我认为这意味着我的回复在我的查询完成之前发送。
在循环中使用异步操作进行循环时,您必须使用 await
对循环进行排序,或者对于并行操作,将循环中的所有承诺收集到一个数组中并使用 Promise.all()
跟踪它们何时完成。这是一种方法:
router.get('/pictures', (req, res, next) => {
Picture.find()
.then(handle404)
.then(pictures => {
pictures = pictures.map(picture => picture.toObject());
return Promise.all(pictures.map(picture => {
return User.findById(picture.owner).then(owner => {
picture.ownerName = owner.username
return picture;
});
}));
}).then(pictures => {
res.status(200).json({ pictures });
}).catch(next);
});
此外,当您在 .then()
处理程序中进行异步操作时,请确保 return 这些承诺,以便将它们链接到链中。
您收到的警告 UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
是因为您正试图向同一个 http 请求发送多个响应。这发生在你的循环中,你试图在循环中执行 res.json(...)
(因此多次)。避免这种情况的方法是从循环中收集结果(在这种情况下使用 Promise.all()
),然后在最后发送一个响应。
router.get('/pictures', (req, res, next) => {
Picture.find()
.then(handle404)
.then(pictures => {
return pictures.map(picture => picture.toObject())
})
.then(pictures => {
pictures.map(picture => {
User.findById(picture.owner)
.then(owner => {
picture.ownerName = owner.username
console.log(pictures, "my picture with owner")
return pictures
})
.then(pictures => res.status(200).json({ pictures: pictures }))
})
})
.catch(next)
})
})
操作顺序:我需要找到所有图片,然后遍历图片数组并找到所有者的用户名,然后在图片数组中添加所有者用户名的键,然后发送响应包含所有者用户名的新图片数组
我想 return 包含找到的所有者名称的图片数组。但是我在设置所有者名称之前发送响应时遇到问题,我不确定如何获得响应等待。如果只有一个所有者的名字没问题,但如果超过一个,我会得到一个错误 -
UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
我认为这意味着我的回复在我的查询完成之前发送。
在循环中使用异步操作进行循环时,您必须使用 await
对循环进行排序,或者对于并行操作,将循环中的所有承诺收集到一个数组中并使用 Promise.all()
跟踪它们何时完成。这是一种方法:
router.get('/pictures', (req, res, next) => {
Picture.find()
.then(handle404)
.then(pictures => {
pictures = pictures.map(picture => picture.toObject());
return Promise.all(pictures.map(picture => {
return User.findById(picture.owner).then(owner => {
picture.ownerName = owner.username
return picture;
});
}));
}).then(pictures => {
res.status(200).json({ pictures });
}).catch(next);
});
此外,当您在 .then()
处理程序中进行异步操作时,请确保 return 这些承诺,以便将它们链接到链中。
您收到的警告 UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
是因为您正试图向同一个 http 请求发送多个响应。这发生在你的循环中,你试图在循环中执行 res.json(...)
(因此多次)。避免这种情况的方法是从循环中收集结果(在这种情况下使用 Promise.all()
),然后在最后发送一个响应。