【问题标题】:Why is the empty array still empty even if I push values in it? [duplicate]为什么即使我在其中推送值,空数组仍然是空的? [复制]
【发布时间】:2019-12-17 09:45:16
【问题描述】:

usersList 是具有字符串值的有效数组, User.findById(userId) 按预期返回用户。 我认为问题在于范围块,因为 forEach 方法和 FindById 方法完美。

我尝试了许多返回每个值的数组方法。 (例如地图和过滤器) 我已经阅读了许多有关高级 MongoDB 技术、范围块和数组方法的文档。

const usersList = camp.usersList;
let users = [];
usersList.forEach((userId) => {
  User.findById(userId, (err, user) => {
    if(err) return res.redirect('/admin/db');
    users.push(user);
  })
})
console.log(users);

输出应该是 [user1, user2, ...],而不是 []。

【问题讨论】:

  • 在将 user 推送到 users 数组之前,请在控制台 (console.log('User is '+user);) 上打印该值。问题可能是从未调用过推送。如果数据库中没有用户。其次,您打印users 数据库查询的时间还没有完成(异步)。
  • User.findById 看起来像一个异步函数
  • User.findById 是异步的吗? forEach 忽略异步功能;除了不对你的函数使用 async/await 之外,你会在你的函数调用 users.push(user) 之前点击 console.log(users)
  • 感谢您的回答,async/await 为我解决了问题!

标签: javascript arrays node.js loops mongoose


【解决方案1】:
async () => {
    const usersList = camp.usersList;
    const users = [];
    for (var userId of usersList)  {
        const user = await User.findById(userId).exec();
        if (!user) return res.redirect('/admin/db');
        users.push(user);
    }
    console.log(users);
}

为了获得更好的性能,您可以使用下面的代码,它不会等待单个请求完成,它会进行并行调用,从而提高性能

async ()=> {
    try {
        const users_promise = usersList.map(userid => User.findById(userid).exec())
        const users = await Promise.all(users_promise);
    } catch(error) {
        res.redirect('/admin/db');
    }
}

【讨论】:

  • 需要注意的是,Nayan 之所以将循环从.forEach 改为是因为.forEach 不支持异步。
  • forEach 使用回调,所以我们不应该在那里使用 await。因此,每当我们需要等待响应时。你不应该使用 forEach。
  • 据我所知,Mongoose 的Model.findById 返回一个Query,而不是一个承诺。我相信你需要打电话给query.exec()
  • @Khauri 你是对的,但结果仍然是 thenable (所以它可以与 await 一起使用)。 mongoosejs.com/docs/queries.html#queries-are-not-promises User.findById(userId).then 基本上是User.findById(userId).exec().then 的快捷方式。
  • Javascript 太棒了
【解决方案2】:

改用 promise 数组

const userPromises = usersList.map(userid => User.findById(userid))

Promise.all(userPromises).then(users => console.log(users))
                         .catch(() => res.redirect('/admin/db'));

【讨论】:

    猜你喜欢
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多