首页 > 解决方案 > Promise.all 不适用于两个 mongodb 查询

问题描述

我正在尝试将后端的三段数据合并到一个对象数组中。我想弄清楚是否有足够的门票可以继续销售。三个数据分别是:

  1. 来自前端的请求,为某个事件购买一定数量的某种类型的门票。这是一个对象数组。

  2. 该活动已售出的该类型门票的总数。

  3. 从我在 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 中的值?

标签: node.jsmongodbpromisemongodb-query

解决方案


我认为这是因为你有一个数组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

推荐阅读