node.js - Promise.all 不适用于两个 mongodb 查询
问题描述
我正在尝试将后端的三段数据合并到一个对象数组中。我想弄清楚是否有足够的门票可以继续销售。三个数据分别是:
来自前端的请求,为某个事件购买一定数量的某种类型的门票。这是一个对象数组。
该活动已售出的该类型门票的总数。
从我在 MongoDB 中创建的事件文档中可出售的该类型门票的数量。
这是使用以下代码工作的。但是,它是同步的,我想异步进行以加快站点速度。
let numTicketsSought = req.body.numTicketsSought.map(e => { return(
Ticket.find({
userEvent: req.body.userEvent,
ticketTypeID: e.ticketTypeID
}).lean().countDocuments()
.then(number => {
e.ticketsSold = number
return e
}))
})
Promise.all(numTicketsSought).then(numTicketsSoughtdata => {
Event.findById(req.body.userEvent)
.lean()
.then(eventdata => {
numTicketsSoughtdata.map(e => {return (
eventdata.tickets.forEach(f => {
if (e.ticketTypeID === f.ticketTypeID){
e.numberOfTickets = f.numberOfTickets
e.ticketsAvailable = e.numberOfTickets - e.ticketsSold
return e
}
})
)})
})
但是,当我尝试异步运行 Ticket.find 和 Event.findbyID(使用 Promise.all)时,代码将无法运行。这是代码:
let numTicketsSought = req.body.numTicketsSought.map(e => { return(
Ticket.find({
userEvent: req.body.userEvent,
ticketTypeID: e.ticketTypeID
}).lean().countDocuments()
.then(number => {
e.ticketsSold = number
return e
}))
})
let eventInfo = Event.findById(req.body.userEvent).select('tickets.ticketTypeID tickets.numberOfTickets')
.then().catch(err => console.log(err))
Promise.all([numTicketsSought, eventInfo]).then(data => {
let numTicketsSought = data[0]
let eventInfo = data[1]
console.log('numTicketsSought', numTicketsSought)
console.log('eventInfo', eventInfo)
numTicketsSought.map(e => {return (
eventInfo.tickets.forEach(f => {
console.log('TRIGGERED')
console.log('e.ticketTypeID ', e.ticketTypeID )
console.log('f.ticketTypeID ', f.ticketTypeID )
console.log('----------------')
if (e.ticketTypeID === f.ticketTypeID){
console.log('MATCHED')
e.numberOfTickets = f.numberOfTickets
e.ticketsAvailable = e.numberOfTickets - e.ticketsSold
return e
}
})
)})
})
这是终端显示的内容:
numTicketsSought [ Promise {
{ ticketType: 'Early Bird',
ticketTypeID: 1,
numTicketsSought: 1,
ticketsSold: 100 } },
Promise {
{ ticketType: 'Early Bird VIP',
ticketTypeID: 2,
numTicketsSought: 2,
ticketsSold: 15 } } ]
eventInfo { _id: 5de147e1ed01a505f1ee0011,
tickets:
[ { ticketTypeID: 1, numberOfTickets: 5 },
{ ticketTypeID: 2, numberOfTickets: 5 },
{ ticketTypeID: 3, numberOfTickets: 10 },
{ ticketTypeID: 4, numberOfTickets: 4 } ] }
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 1
----------------
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 2
----------------
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 3
----------------
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 4
----------------
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 1
----------------
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 2
----------------
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 3
----------------
TRIGGERED
e.ticketTypeID undefined
f.ticketTypeID 4
----------------
我做错了什么阻止 Promise.all 使用第一个 Promise 中的值?
解决方案
我认为这是因为你有一个数组Promises
不是一个Promise
let numTicketsSought = req.body.numTicketsSought.map(e => { return(
Ticket.find({
userEvent: req.body.userEvent,
ticketTypeID: e.ticketTypeID
}).lean().countDocuments()
.then(number => {
e.ticketsSold = number
return e
}))
})
这里的问题是Array.prototype.map
它将返回一个数组。
Promise.All([])
在你的情况下你正在做Promise.all([[],])
你需要解开你的承诺并将它们连接在一起
numTicketsSought.push(eventInfo);
Promise.all(numTicketsSought) // <-- rename numTicketsSought to something better like promisesToComplete
推荐阅读
- sql - 用于 SQL 访问 Access 数据库的联接问题
- algorithm - 比较 2 个词的相似度度量
- file - Vaadin 8:扩展 FiledownLoader
- php - 无法向 PHPGraphLib 的远程 API 添加和呈现多集数据
- tensorflow - 热启动 Distribute.MirroredStrategy 和 tf.Estimator
- sql-server - SQL Server CMDEXEC - 访问被拒绝
- python - EC2 上的 Spark 集群仅使用一个节点
- java - 多个应用程序 ID 的附加安装程序
- java - Log4j - 如何在 14 天后滚动日志文件
- javascript - GraphQL:架构不可用