我在使用异步调用时遇到了麻烦。这是给我带来麻烦的代码片段

company.find({ managerID: req.session.manager.managerID })
        .exec((err, _companies) => {
            if(err)
                return res.status(500).send({ message: "Uh, oh! Something went wrong." });
            else {
                var data = [];
                var i = 0;
                _companies.forEach(c => {
                    user.find({ companyID: c._id, status: 0})
                    .then(_user => {
                            // console.log(_user);
                            var dummy = {
                                companyID: c._id,
                                companyName: c.companyName,
                                selectedCurrency: c.selectedCurrency,
                                metrics: c.metrics,
                                headAdmin: _user[0].email,
                                headName: _user[0].designer
                            };
                            console.log(dummy);
                            data.push(dummy);
                            console.log(data);
                            i++;
                    }).catch(err => {
                        return res.status(500).send({ message: "Uh, oh! Something went wrong." });
                    });
                });
                if(i == _companies.length)
                    return res.status(200).send({ data: data });
            }
        });


我的数据对象是在正确形成对象之前发送的。

我试图从.exec切换到.then,希望它可以修复它,甚至试图仅在循环完成后才返回(甚至不返回空数组)。

每当我在console.log("hi")之前调用return res.status(200).send({ data: data})时,它总是在console.log(dummy)之前打印

会等待解决此问题,如果是,我应该如何使用它,因为我对如何使用它不熟悉?

最佳答案

Array.prototype.forEach是同步工作的,因此它不会等待内部的异步操作(例如user.find())。因此,i == _companies.length在异步操作完成之前计算为true

如另一个答案中所建议,您可以通过将所有待处理的promise收集到数组中并将其传递给Promise.all()来解决此问题。在您的方案中,这可能类似于以下内容:

company.find({ managerID: req.session.manager.managerID })
  .exec((err, _companies) => {
    if (err) {
      return res.status(500).send({ message: "Uh, oh! Something went wrong." });
    }
    const results = _companies.map(c =>
      user.find({ companyID: c._id, status: 0})
        .then(_user => ({
            companyID: c._id,
            companyName: c.companyName,
            selectedCurrency: c.selectedCurrency,
            metrics: c.metrics,
            headAdmin: _user[0].email,
            headName: _user[0].designer
        }))
    );
    return Promise.all(results)
      .then(data => res.status(200).send({ data: data }))
      .catch((err) => res.status(500).send({ message: "Uh, oh! Something went wrong." }));
  });

关于node.js - NodeJS异步。在正确形成对象之前发送的标题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58880074/

10-16 18:20