Javascript 对数据库的异步请求出现问题

Javascript 对数据库的异步请求出现问题,javascript,node.js,express,mysql2,Javascript,Node.js,Express,Mysql2,我有一个PlaceYourOrder按钮,它调用/orderRegistration,然后根据订单更新库存产品的数量,并将确认的订单发送到电子邮件 const orderStatus = ['Confirmed', 'Not confirmed']; router.post('/orderRegistration', (req, res) => { if (req.session.successAuthentication === true && req.s

我有一个PlaceYourOrder按钮,它调用/orderRegistration,然后根据订单更新库存产品的数量,并将确认的订单发送到电子邮件

const orderStatus = ['Confirmed', 'Not confirmed'];
router.post('/orderRegistration', (req, res) => {
  if (req.session.successAuthentication === true &&
      req.session.isWorker === false) {
    conn.query(`SELECT  orders.id,
                        products.product_id,
                        products.product_name,
                        products.product_amount,
                        order_product.count 
                FROM orders INNER JOIN order_product
                ON orders.id = order_product.order_id INNER JOIN products
                ON order_product.product_id = products.product_id
                WHERE orders.id IN(
                    SELECT id 
                    FROM orders
                    WHERE user_id=${req.session.userId}
                    AND status = '${orderStatus[1]}')
                AND orders.status = '${orderStatus[1]}';`, (err, selProductId) => {
      if (err) {throw err;}
      if (selProductId.length > 0) {
        let dateNow = new Date(); 
        let prepDate = {
          day: (dateNow.getDate() < 10) ? `0${dateNow.getDate()}` : dateNow.getDate(),
          month: ( dateNow.getMonth() + 1 < 10) ? `0${dateNow.getMonth() + 1}` : dateNow.getMonth() + 1,
          year: dateNow.getFullYear(),
          hours: (dateNow.getHours() < 10) ? `0${dateNow.getHours()}` : dateNow.getHours(),
          minutes: (dateNow.getMinutes() < 10) ? `0${dateNow.getMinutes()}` : dateNow.getMinutes()
        };
        let orderDate =  `${prepDate.day}.${prepDate.month}.${prepDate.year} ${prepDate.hours}:${prepDate.minutes}`;
        let productsInOrderHTML = '';
        let totalAmount = 0;
        for (let i = 0; i < selProductId.length; i++) {
          conn.query(`UPDATE products
                      SET products.product_count_stock = products.product_count_stock - ${selProductId[i].count}
                      WHERE products.product_id = ${selProductId[i].product_id}`, err => {
            if (err) {throw err;}
            productsInOrderHTML += `<tr>
                                      <td>
                                        ${selProductId[i].product_name}
                                      </td>
                                      <td>
                                        ${selProductId[i].count}
                                      </td>
                                      <td>
                                        ${selProductId[i].product_amount}
                                      </td>
                                    </tr>`;
            totalAmount +=  selProductId[i].count *
                            selProductId[i].product_amount;
            if(i === selProductId.length - 1) {
              console.log('totalAmount: ' + totalAmount);
            }
          });
        }
      } else {
        res.send('error');
      }
    });        
  } else {
    res.send('error');
  }
});
也就是说,有时totalAmount可能有时间更新所有产品,有时则没有,结果表明totalAmount将不等于用户订购产品的成本

如何重写查询或重构查询,以避免再次发生这种情况


另外,抱歉用英语,我是通过翻译翻译的,因为我会说俄语。我可能也漏掉了一些东西,所以必要时请纠正我

对数据库的查询是异步的,这意味着nodejs的eventloop将把它们传递到队列,循环将继续,因此您必须等待它们

试试这个

const orderStatus=[“已确认”、“未确认”]; 路由器.post'/orderRegistration',异步请求,res=>{ 如果req.session.successAuthentication==true&& req.session.isWorker===false{ 等待conn.promise.query`SELECT orders.id, products.product\u id, products.product_名称, 产品。产品数量, 订单数量 从订单内部连接订单\产品 ON orders.id=order\u product.order\u id内部联接产品 订单上的\u product.product\u id=产品.product\u id orders.id在哪里 选择id 从命令 其中user_id=${req.session.userId} 和状态=“${orderStatus[1]}” 和orders.status='${orderStatus[1]}';`,异步错误,selProductId=>{ 如果出错{ 犯错误; } 如果selProductId.length>0{ 让dateNow=新日期; 让prepDate={ day:dateNow.getDate<10?`0${dateNow.getDate}`:dateNow.getDate, 月份:dateNow.getMonth+1<10?`0${dateNow.getMonth+1}`:dateNow.getMonth+1, 年份:dateNow.getFullYear, 小时数:dateNow.getHours<10?`0${dateNow.getHours}`:dateNow.getHours, 分钟数:dateNow.getMinutes<10?`0${dateNow.getMinutes}`:dateNow.getMinutes }; 让orderDate=`${prepDate.day}.${prepDate.month}.${prepDate.year}${prepDate.hours}:${prepDate.minutes}`; 设productsInOrderHTML=; 设totalAmount=0; 对于let i=0;i{ 如果出错{ 犯错误; } productsInOrderHTML+=` ${selProductId[i]。产品名称} ${selProductId[i].count} ${selProductId[i]。产品\金额} `; totalAmount+=selProductId[i]。计数* selProductId[i]。产品数量; 如果i==selProductId.length-1{ console.log'totalAmount:'+totalAmount; } }; } }否则{ res.send'error'; } }; }否则{ res.send'error'; } };
这回答了你的问题吗?错误:wait仅在for looperror中的异步函数中有效。错误:您已尝试调用。然后,.catch,或对非承诺的查询结果调用wait,这是一个编程错误。尝试调用con.promise.query,或者要求“mysql2/promise”而不是“mysql2”以获得与promise兼容的查询界面版本。我更新了答案,您所要做的就是在查询后添加promise,或者要求“mysql2/promise”而不是“mysql2”
if(i === selProductId.length - 1) {
    console.log('totalAmount: ' + totalAmount);
}