不知道如何等待 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)
.
我有一个包含用户 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)
.