我从数据库中获取电影记录,并且电影记录有电影中演员的 ID 列表,因此我向数据库发送另一个请求以获取演员,然后我将替换该列表ID 与演员列表。这段代码可以工作,但当然它很糟糕,因为 setTimeout 所以我如何在上面的代码完成后执行 setTimeout 中的代码
const getMovie = async (req, res) => {
let actors = [];
Movie.findById(req.params.id)
.then(movie => {
if (movie == null) res.json('This movie does not exist')
else
{
movie.Actors.forEach(element => {
Actor.findById(element)
.then((a) => {
actors.push(a);
})
});
setTimeout(() => {
movie.Actors = actors;
res.json(movie);
}, 1000);
}
})
.catch(err => res.status(400).json(`Error: ${err}`))
}
我尝试使用 Promise 但它不起作用,但当然我是一个冒名顶替者,所以我可能以错误的方式实现它
首先,您的代码表现得“运气好”,因为您假设所有参与者都将在 1000 毫秒的超时时间内从数据库中获取,但这可能并不总是正确的。
话虽如此,您在这里想要的是
await
完成所有承诺。最简单的方法是使用 Javascript 的 Promise.all
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all)
你的代码看起来像这样:
const actors = await Promise.all(movie.Actors.map(async actor => {
return Actor.findById(element)
}))
这将用结果填充
actors
变量。
然后你可以这样做:
movie.Actors = actors;
res.json(movie);
当然你需要制作这个功能
.then(movie => {
async
,但这不应该影响其他任何事情。
您也可以使用 rxjs (https://rxjs.dev/) 实现相同的效果,但这比
Promise.all
更复杂一点。