【问题标题】:Nodejs array push is empty when placed after awaitNodejs数组推送在等待之后为空
【发布时间】:2022-11-13 00:56:17
【问题描述】:

我正在尝试遍历一个数组,从数据库中获取每只股票的数量和价格,进行一些计算并将它们推送到一个数组

但是在从数据库中获取数量和价格并推送到数组之后

该数组仍然是空的

如果我删除这一行

const db_stock = await Stocks.findById(stock.stockId);

一切正常

但是,如果我将 await 添加回来,则数组变为空

import mongoose from "mongoose";
import { response } from "express";
import  StockDispatches  from "../models/StockDispatch.js"
import  Stocks  from "../models/Stocks.js"
import { createError } from "../error.js";
import validator from 'express-validator'
const { validationResult } = validator
import { generateRamdom } from "../utils/Utils.js"

export const createStockDispatched = async (req, res, next) => {
    
  
    const error = validationResult(req).formatWith(({ msg }) => msg);
    const trx_id =  generateRamdom(30);
    let quantity = 0;
    let total = 0;
    let dispatchedTotal = 0;
    const hasError = !error.isEmpty();

    if (hasError) {
      res.status(422).json({ error: error.array() });
    } else {
        

        const options={ordered: true}; 
        let user_stocks =[];
        req.body.stocks.map(async (stock, index) => {
            let total = stock.price * stock.quantity

            const db_stock = await Stocks.findById(stock.stockId);
            if(!db_stock) return res.status(404).json({msg: "Stock Not Found."})
            
            if( stock.quantity > db_stock.quantity)
            return res.status(208).json({msg: `Quantity of ${stock.name} is greater than what we have in database`})

            quantity = db_stock.quantity - stock.quantity;
            total = quantity * db_stock.price;

            const updated_stock = await Stocks.findByIdAndUpdate(stock.id, {quantity, total},{$new: true})

            
            dispatchedTotal = stock.quantity * db_stock.price;
            user_stocks.push("samson")
            user_stocks.push({...stock, staffId: req.user.id, total: dispatchedTotal, trx_id, stockId: stock.id, price: db_stock.price})

        });
        
        

        try{
            const stockDispatched = await StockDispatches.insertMany(user_stocks, options);
            if(!stockDispatched) return res.status(500).json({msg: "Error. Please try again."})
            
            return res.status(200).json({msg: "Stock uploaded successfully.."})
        }catch(error){
            next(error)
        }
      
      
    }
}

【问题讨论】:

  • Uhhh .map() 不支持承诺,也不会阻塞 await 的循环,所以你只会从 req.body.stocks.map 得到一系列承诺,你需要等待 Promise.all() 所以你知道当一切都完成时。现在你假装.map() 正在阻塞并等待你在它的回调中使用的promise,而实际上它不是。因此,您尝试在user_stocks 包含任何值之前使用它。
  • 最简单的建议是将req.body.stocks.map() 更改为for (let [index, stock] of req.body.stocks.entries()) { ... },因为for 循环是promise-aware 的,并且会在循环体内暂停await 的循环。
  • @jfriend00 成功了。谢谢

标签: node.js database mongodb mongoose


【解决方案1】:

解决此问题的最简单方法是更改

req.body.stocks.map() 

至:

for (let [index, stock] of req.body.stocks.entries()) { ... } 

因为 for 循环是 promise-aware 并且会在循环体中为你的 await 暂停循环,而 .map() 不会为回调中的 await 暂停它的循环。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-13
    • 2021-06-09
    • 2017-08-16
    • 2020-01-11
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    相关资源
    最近更新 更多