【问题标题】:Problem creating an object within forEach loop javascript [duplicate]在forEach循环javascript中创建对象时出现问题[重复]
【发布时间】:2020-04-29 11:18:48
【问题描述】:

我一直在尝试使用从 MongoDB 数据库中提取的数据创建一个 JSON 对象。

最后一行 res.status(200).json(userData) 似乎之前返回了响应 数据处理结束,所以我得到一个没有处理数据的空对象作为响应。关于如何解决这个问题的任何想法?

             // chats are defined before, but excluded here to make a code easier to read
             let userData = {};
             chats.forEach(function(chat){
               let chatId = chat.id;
               let userIds = chat['userIds'];
               UserAccountingData.find({userId: {$in : userIds}}, function(err, userAccountingData){
                  if(err){
                    console.log(err);
                    res.status(404).json('User data not found.');
                    return;
                  } else {
                  userAccountingData.forEach(function(data){
                    console.log({
                      imageUrl: data.imageUrl,
                      firstName: data.firstName,
                      lastName: data.lastName
                    });
                    userData[data.userId] = {
                      imageUrl: data.imageUrl,
                      firstName: data.firstName,
                      lastName: data.lastName
                    };
                  });
                }
               });
             });
             res.status(200).json(userData);

Console.log 显示有数据来自数据库:

{ imageUrl: 'www.test.de', firstName: 'Fender', lastName: 'Fen' }
{ imageUrl: 'www.test.de', firstName: 'Baveler', lastName: 'Bav' }

感谢您的宝贵时间

【问题讨论】:

  • 您能确认 data.userId 中的内容吗?
  • 它只是一个字符串形式的聊天对象 ID,如下所示:“5b1232142512c6166c04e655”
  • 因为您的 UserAccountingData.find 似乎是一个异步调用。当您返回响应时,它不会被填满。尝试填充userData 对象并将数据作为承诺返回。

标签: javascript mongodb foreach


【解决方案1】:

这是因为 UserAccountingData.find 是异步运行的。所以我们需要在这段代码中添加 async/await 逻辑。

首先,定义查找函数。

const findUserAccountingData = (userIds) => new Promise((resolve, reject) => {
    UserAccountingData.find({ userId: { $in: userIds } }, function (err, userAccountingData) {
        if (err) {
            return reject(err);
        }

        resolve(userAccountingData)
    })
});

接下来,像下面这样修改原始代码。

let userData = {};
try {
    for (let chat of chats) {
        let chatId = chat.id;
        let userIds = chat['userIds'];
        const userAccountingData = await findUserAccountingData(userIds)
        userAccountingData.forEach(function (data) {
            console.log({
                imageUrl: data.imageUrl,
                firstName: data.firstName,
                lastName: data.lastName
            });
            userData[data.userId] = {
                imageUrl: data.imageUrl,
                firstName: data.firstName,
                lastName: data.lastName
            };
        });
    }
} catch (error) {
    console.log(error);
    // res.status(404).json('User data not found.');   // error doesn't occur when user data not exists.
    res.status(500).json(JSON.stringify(error));
}
res.status(200).json(userData);

最后你需要将调用函数标记为异步。

【讨论】:

  • 当前代码串行运行。我们可以修改此代码以提高性能。也就是说,我们可以编写与 Promise.all() 完全相同的代码
  • 它的工作方式与现在设想的一样。我不知道这种技术。感谢您提供额外的 cmets,我将阅读此主题。
猜你喜欢
  • 2017-12-27
  • 1970-01-01
  • 1970-01-01
  • 2021-05-04
  • 2013-06-10
  • 2015-09-21
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多