不知道如何等待 Promise

Cannot figure out how to wait for Promise

我有一个包含用户 ID 的数组,我需要找出每个 ID 的名称,然后 return 将它们放在一个数组中。 我可以使用 knex 从数据库中获取用户名并将它们推送到一个数组中,但是当我尝试发送数据时它始终是一个空数组。

我不太擅长 Promises,所以不知道如何应用到我的项目中。

const userId = [10,11,12,13]
let users = []

userId.map(id => {
    db.select('name').from('users').where('user_id', id)
    .then(user => {
        users.push(user)
    })
})
res.json(users)

我希望响应等到循环完成并发送用户数组。

首先你需要等待所有的promise在运行res.json(...)

之前完成

其次,你不应该在 promise 解析后改变外部变量(promise 解析的顺序会改变你的输出,这不好。

像这样的东西应该可以正常工作

const userId = [10,11,12,13]

// map userId array to promise array
// Promise.all aggregates a promise array into one big promise that resolves when all promises resolve (and preserves array order)
Promise.all(
  userId.map(id =>
    db
      .select("name")
      .from("users")
      .where("user_id", id)
  )
)
  .then(users => res.json(users))
  .catch(e => console.error("Error::", e));

/*handle error in the catch block*/

/* visual example of Promise.all.then block
Promise.all([           users = [
   getUser(10),    ->     {userId: 10, ....}
   getUser(11),    ->     {userId: 11, ....}
   getUser(12)     ->     {userId: 12, ....}
])                      ]

*/

您的 map 正在创建一个 undefined 的数组,因为您的回调函数没有 return 任何东西。如果我们稍微调整一下,它会创建一个 promises 数组,这正是 Promise.all 所期望的。 :-) 所以:

const userId = [10,11,12,13]
Promise.all(
    userId.map(id => db.select('name').from('users').where('user_id', id))
)
.then(users => {    // `users` is an array of users, in the same order as the IDs
    res.json(users);
})
.catch(error => {
    // Render an error response
});

作为备选答案,这里介绍了如何针对此特定查询访问数据库 1 次,这意味着您无需等待多个 Promise 并减少数据库的负载

knex.raw(
  'select name from users where user_id in (' + userId.map(_ => '?').join(',') + ')', 
  [...userId]
);

你要Promise.all(),见here

尝试

const userId = [10,11,12,13]

let users = userId.map(id => new Promise(resolve => {
    db.select('name').from('users').where('user_id', id)
    .then(user => {
        resolve(user)
    })
}))
Promise.all(users).then(()=>res.json(users))

这里users是一组promise。一旦所有问题都得到解决,请执行 res.json(users).