You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中使用await后数组push操作后数组为空问题求助

问题描述

尝试遍历数组,从数据库获取每支股票的数量和价格,计算后将结果推入数组。但执行const db_stock = await Stocks.findById(stock.stockId);这个数据库查询并push后,数组始终为空。移除该代码后功能正常,加回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)
        }
      
      
    }
}
问题原因
  1. map与async/await不兼容:map函数会直接返回一个Promise数组,但代码中没有等待这些Promise执行完成,就立刻执行了StockDispatches.insertMany(user_stocks, options)。此时user_stocks还没被填充任何数据,自然为空。
  2. 错误的响应方式:在map的异步回调里直接return res.status(...).json(...),可能会导致多次响应同一个请求,引发错误。
解决方案

将map替换为for...of循环,它能和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) {
        return res.status(422).json({ error: error.array() });
    } 

    try {
        const options = { ordered: true }; 
        let user_stocks = [];
        
        // 用for...of替代map,确保await执行完成后再推进数组
        for (const stock of req.body.stocks) {
            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;

            // 修正参数:用stock.stockId匹配数据库中的股票ID
            await Stocks.findByIdAndUpdate(stock.stockId, { 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.stockId,
                price: db_stock.price
            });
        }
        
        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);
    }
}
额外说明
  • 原代码中Stocks.findByIdAndUpdate(stock.id, ...)存在参数错误,应该使用stock.stockId匹配数据库中的股票ID,已在解决方案中修正。
  • 使用for...of可以保证异步操作的顺序执行,避免并发修改导致的逻辑错误。

内容的提问来源于stack exchange,提问作者etranz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 22:35:38