Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

139
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!