Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

142
Vistas
Node.js/ - ¿MongoDB async/espera un comportamiento extraño?

Aquí, productIds tiene ID de todos los artículos pedidos en una matriz como ["1294382", "2913892"]

Entonces, estoy tratando de obtener todos los elementos con esas ID de la base de datos de MongoDB. Estoy mapeando a través de cada uno de ellos y los almaceno en la matriz de elementos ordenados. Para que pueda acceder al precio (o cualquier propiedad) del artículo en la base de datos.

 productRouter.post("/", async (req, res) => { const productIds = req.body.orderedItems.map((item) => item.id); let orderedItems = []; productIds.map(async (productId) => { const d = await Product.findById(productId); orderedItems.push(d); }); const unusedVariable = await Product.findById("61...da1"); //If i delete that line (or only await), orderedItems returns empty array. console.log(orderedItems); });

Ahora, la salida esperada es:

 [ { _id: new ObjectId("614632cc8aa9513567dfbca4"), name: 'ürün1', desc: 'ürün1 açıklama', price: 50, __v: 0 }, { _id: new ObjectId("614632cc8aa9513567dfbca2"), name: 'kartal kupa', desc: 'kartal resimli kupa', price: 50, __v: 0 } ]

Y obtengo ese resultado, pero solo si tengo la línea Variable no utilizada con espera. Si elimino esa línea, o elimino "esperar" de allí, el resultado que obtengo es: [] . Entonces, una matriz vacía en lugar de llena de objetos.

Por qué ? ¿Y cómo resuelvo eso (simplemente dejo unusuedVariable allí?)? ¿Qué tan malo es este código?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Tienes un problema de concurrencia. ​No hay nada inusual, no está esperando que terminen las promesas en (1) . La única razón por la que su código funciona es que MongoDB en su caso usa una sola conexión y, por lo tanto, (2) se pone en cola y se completa solo después de que (1) (todos ellos) se completan (es una coincidencia afortunada suya).

 productRouter.post("/", async (req, res) => { ​const productIds = req.body.orderedItems.map((item) => item.id); ​let orderedItems = []; ​productIds.map(async (productId) => { // (1) ​const d = await Product.findById(productId); ​orderedItems.push(d); ​}); ​const unusedVariable = await Product.findById("61...da1"); // (2) ​console.log(orderedItems); });

Como se mencionó, ni map ni forEach admiten promesas (y probablemente nunca lo harán, debido a la compatibilidad con versiones anteriores), por lo tanto, debe usar Promise.all , que puede brindarle cierta concurrencia, o usar simple for que sea compatible con la sintaxis async/await .

 productRouter.post("/", async (req, res) => { const productIds = req.body.orderedItems.map((item) => item.id); let orderedItems = []; for (const productId: productIds) { orderedItems.push(await Product.findById(productId)); } console.log(orderedItems); });

O

 productRouter.post("/", async (req, res) => { const productIds = req.body.orderedItems.map((item) => item.id); const orderedItems = await Promise.all( productIds.map(productId => Product.findById(productId)) ); console.log(orderedItems); });

Fuera de contexto

Como se menciona en los comentarios, debe considerar usar el operador $in , que reducirá drásticamente la cantidad de consultas en su base de datos:

 productRouter.post("/", async (req, res) => { const productIds = req.body.orderedItems.map((item) => item.id); const orderedItems = Product.find({_id: {$in: productIds}}); console.log(orderedItems); });

Más aquí

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda