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

JavaScript构建产品过滤函数时Promise.all未收集到Promise问题求助

问题:Promise.all 收集异步查询结果失败,数组始终为空

我正在构建一个产品过滤函数,传入的城市(Cities)和分类(Categories)参数格式为['New York']、['Cars'],需要遍历这些参数查询对应城市或分类的产品,最终汇总结果返回给用户。

当前遇到的问题:在async回调里用console.log能看到查询到的产品,但把结果push到promises数组后,调用Promise.all时这个数组是空的,导致无法返回结果。我原本想把Promise收集到promises数组,通过Promise.all等全部解析后汇总产品,但promises始终为空。

使用MongoDB和Mongoose做产品查询,.find方法能返回匹配的产品数据,相关代码如下:

import { Product } from "../../models";
import { Response } from "../../utils";

export default async function ProductsFilters(req, res) {
  try {
    const { Cities, Categories } = req.body;

    let products = [];
    let promises = [];

    if (Cities.length > 0) {
      Cities.map(async (city) => {
        const results = await Product.find({ City: city });
        return promises.push(results);
      });
    }

    if (Categories.length > 0) {
      Categories.map(async (category) => {
        const results = await Product.find({ Category: category });
        return promises.push(results);
      });
    }

    const results = await Promise.all(promises);
    results.map((result) => products.push(result));

    if (products.length > 0) Response( res, 200, true, "Të gjitha produktet u morën me sukses.", products);
    else Response(res, 404, false, "Asnjë produkt nuk u gjet në platformë.", null);
  } catch (error) {
    Response( res, 500, false, "Gabim i brendshëm i serverit gjatë gjetjes së produkteve.", null);
  }
}

问题根源

你在map遍历Cities和Categories时用了async回调,map会立刻返回一个Promise数组,但你没把这些Promise存到promises里,反而在回调内部await查询结果后再push(此时push的是查询结果,不是Promise)。而且因为async回调是异步执行的,当代码走到Promise.all(promises)这一行时,所有push操作还没跑完,所以promises数组是空的。

修正方案

直接把Product.find返回的Promise收集到promises数组里,不用在map回调里await,等所有Promise都收集完再用Promise.all等待执行完成,最后合并结果。另外可以根据需求给产品去重(避免同一个产品被城市和分类查询同时命中)。

修正后的代码:

import { Product } from "../../models";
import { Response } from "../../utils";

export default async function ProductsFilters(req, res) {
  try {
    const { Cities, Categories } = req.body;
    const promises = [];

    // 收集城市查询的Promise
    if (Cities.length > 0) {
      Cities.forEach(city => {
        promises.push(Product.find({ City: city }));
      });
    }

    // 收集分类查询的Promise
    if (Categories.length > 0) {
      Categories.forEach(category => {
        promises.push(Product.find({ Category: category }));
      });
    }

    // 等待所有查询完成
    const results = await Promise.all(promises);
    
    // 扁平化结果数组(每个find返回的是数组,flat把嵌套数组展开)
    const products = results.flat();

    // 可选:去重,用_id作为唯一标识
    // const uniqueProducts = [...new Map(products.map(item => [item._id, item])).values()];

    if (products.length > 0) {
      Response(res, 200, true, "所有产品获取成功。", products);
    } else {
      Response(res, 404, false, "平台上未找到任何产品。", null);
    }
  } catch (error) {
    Response(res, 500, false, "服务器内部错误,获取产品失败。", null);
  }
}

额外优化建议

用MongoDB的$in操作符可以减少查询次数,提升性能。比如不需要循环每个城市单独查,直接一次查询匹配所有城市:

if (Cities.length > 0) {
  promises.push(Product.find({ City: { $in: Cities } }));
}
if (Categories.length > 0) {
  promises.push(Product.find({ Category: { $in: Categories } }));
}

这样不管有多少个城市或分类,都只需要各发起一次数据库查询,比循环查询效率高很多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 08:55:23