NodeJS: cómo usar async.js para procesar una lista de elementos en la base de datos

Tengo este problema: obtengo una lista de elementos de una API y tengo que guardarlos en la base de datos. Para cada uno de ellos tengo que mostrar algunos comentarios, como “- nombre del elemento. Guardar en DB …” y después de guardarlo, mostrar algo como “¡Éxito! Siguiente …”.

Estoy usando un enlace asíncrono para recorrer en iteración los elementos de la matriz y guardar en la base de datos. El problema es que los mensajes no se sincronizan. Muestra un montón del mensaje del nombre del elemento y después de un montón del mensaje de éxito. Mi código de abajo.

var saveInDB = function saveInDB(item, callback) { console.log(' - ' + item.market_name + ' .......'); // Simulating some delay setTimeout(function () { console.log('Success! Next....'); callback(null); }, 3000); } util.getJsonFromUrl(API_URL, function (err, data) { if (err || !data || !data.results || data.results.length == 0) { console.log('BAD'); } else { console.log('Items downloaded...'); async.each( data.results, function (item, callback) { saveInDB(item, callback); }, function (err) { if (err) { console.log('ERROR'); } else { console.log('Success!'); } } ); } }); 

Sí, he intentado usar .series pero no puedo hacerlo funcionar. Estaba buscando ejemplos y todavía no entiendo cómo simplemente pasar el elemento como en .each.

¿Me puedes ayudar? Gracias de antemano por cualquier ayuda.

Basado en la documentación async usando async.each

Aplica la función iterar a cada elemento en arr, en paralelo.

Y mira que incluso advirtieron que esto no conserva el orden ya que es paralelo:

Tenga en cuenta que, dado que esta función se aplica en iteración a cada elemento en paralelo, no hay garantía de que las funciones de iteración se completen en orden.

Si entiendo correctamente, desea que sus elementos (asumiendo que tiene A, B, C) se ejecuten en el siguiente orden:

 //This uses async.eachSeries For each - A SaveInDB called. Timeout set. Waiting to timeout ... Processing DB transaction for > A ....... Done. Success! Next.... For each - B SaveInDB called. Timeout set. Waiting to timeout ... Processing DB transaction for > B ....... Done. Success! Next.... For each - C SaveInDB called. Timeout set. Waiting to timeout ... Processing DB transaction for > C ....... Done. Success! Next.... 

Y no en el siguiente orden (o quizás diferente, es paralelo, no hay orden garantizado):

 //uses async.each For each - A SaveInDB called. Timeout set. Waiting to timeout ... For each - B SaveInDB called. Timeout set. Waiting to timeout ... For each - C SaveInDB called. Timeout set. Waiting to timeout ... Processing DB transaction for > A ....... Done. Success! Next.... Processing DB transaction for > B ....... Done. Success! Next.... Processing DB transaction for > C ....... Done. Success! Next.... 

Así que cambie su método de async.each a async.eachSeries y asegúrese de no confundirse, consulte la función saveInDB continuación.

 function saveInDB(item, callback) { //this will not wait for timeout. console.log('SaveInDB called.'); // Simulating some delay setTimeout(function () { //everything in this block waits for timeout. console.log('Processing DB transaction for > ' + item + ' ....... Done.'); console.log('Success! Next....'); callback(null) }, 5000); //this will not wait for timeout console.log('Timeout set. Waiting to timeout ...'); } 

Le daría una oportunidad con una base de datos real, en lugar de una simulación con un tiempo de espera. Tenga cuidado con el tiempo de espera, consulte la documentación a continuación :

Es importante tener en cuenta que su callback probablemente no será llamada exactamente en milisegundos de retardo. Node.js no ofrece ninguna garantía sobre el momento exacto en el que se activará la callback, ni de las cosas de pedido. La callback se llamará como Lo más cerca posible del tiempo especificado.

  async.each(data.results, function (result, cb_results) { //try your here cb_results(); }, function (err) { if (err) { throw err; } }); 

Ejemplo:

  var returnData = []; async.each(data.results, function (result, cb_results) { var myJson = {}; myJson.id = result.id; ................ returnData.push(myJson); cb_results(); }, function (err) { if (err) { throw err; } callback(returnData); });