简体   繁体   English

无法解决Javascript中的所有承诺

[英]Can't resolve all the promises in Javascript

I'm building a filter function. I have categories and cities, that come like this: ['New York'], ['Cars'] , and I'm iterating them to find the products of that category or city.我正在构建一个过滤器 function。我有类别和城市,它们是这样的: ['New York'], ['Cars'] ,我正在迭代它们以找到该类别或城市的产品。 The idea is to put on the products variable the products that come from each city, or category, and then return them to the user.这个想法是将来自每个城市或类别的产品放在products变量中,然后将它们返回给用户。

I fail to return them because when I console log products in the async function it's displaying the products, but although I push thos in the promises array, that array is empty when I call Promise.all .我未能归还它们,因为当我在异步 function 中控制日志products时,它正在显示产品,但尽管我将它们推送到promises数组中,但当我调用Promise.all时该数组为空。

I know that I need the promises to resolve so I expect to collect them in promises and to await their resolution with Promise.all at the end and convert the data and return all products collected, but the promises array is empty.我知道我需要承诺来解决,所以我希望在promises中收集它们并在最后等待Promise.all的解决并转换数据并返回所有收集的产品,但promises数组为空。

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);
  }
}

I'm using Mongo Database and Mongoose to fetch the products, so .find function is returning the products that it matches.我正在使用 Mongo 数据库和 Mongoose 来获取产品,因此.find function 返回它匹配的产品。

The the map method is synchronous even when you pass it a callback that is asynchronous: map方法是同步的,即使您向它传递异步回调也是如此:

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

Those callbacks will return as soon as they encounter await , so the promises array will still be empty when the .map() call returns.这些回调会在遇到await时立即返回,因此当.map()调用返回时, promises数组仍然为空。

Also map returns an array, which you ignore. map返回一个数组,您忽略它。 Instead you call push inside the map callback.相反,您在map回调中调用push That is bad practice.那是不好的做法。 If you don't expect a returned array, then don't use map , but forEach or for .如果您不期望返回数组,则不要使用map ,而是forEachfor If you do want to populate an array, then take benefit from the array returned by map .如果您确实想要填充一个数组,那么可以利用map返回的数组。

Here is a rewrite:这是一个重写:

async function ProductsFilters(req, res) {
    try {
        const { Cities, Categories } = req.body;
        const products = await Promise.all([
            ...Cities.map(async (City) => Product.find({ City })),
            ...Categories.map(async (Category) => Product.find({ Category }))
        ]);
        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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM