处理异步 JS

问题描述 投票:0回答:1

我从数据库中获取电影记录,并且电影记录有电影中演员的 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 但它不起作用,但当然我是一个冒名顶替者,所以我可能以错误的方式实现它

javascript asynchronous async-await mern
1个回答
0
投票

首先,您的代码表现得“运气好”,因为您假设所有参与者都将在 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
更复杂一点。

© www.soinside.com 2019 - 2024. All rights reserved.