Estoy tratando de guardar varios registros en la base de datos usando asíncrono, pero siempre termino en un registro sobrescribiendo a otros.
Aquí está mi lógica:
var deferred = q.defer(); var records = [{emp_id:1, got_bonus: true},{emp_id:2, got_bonus: false},{emp_id:3, got_bonus: true}]; async.each(records, function(record, next){ saveRecord(record) .then(){ next(null); }); }, function(){ deferred.resolve(); }); function saveRecord(record){ record['activity_type'] = 'bonus'; db_module.save(record); } db_module.js ---------------- function saveRecord(record){ var deferred = q.defer(); checkDuplicate(record) .then(function(isDuplicate)){ if(!isDuplicate){ knex('employees').insert(record); deferred.resolve(); } }); } } function checkDuplicate(record){ return knex('employees') .where({'emp_id': record['emp_id']}) .then(function(rows){ return rows && rows.length > 0; }); }Mi problema es que incluso usando async, el código no está esperando que se guarde el primer registro y luego se guarda a continuación. El resultado del código anterior en la tabla de la base de datos es:
emp_id got_bonus ------- ---------- 3 true 3 false 3 truela salida esperada es:
emp_id got_bonus ------- ---------- 1 true 2 false 3 trueIntenté usar async.waterfall pero recibí el mismo error. No sé cómo usar el módulo de sincronización.
¿Por qué no guarda sus datos de one shot vez?
var records = [ {emp_id:1, got_bonus: true}, {emp_id:2, got_bonus: false}, {emp_id:3, got_bonus: true} ]; var modifiedRecords = records.map((i) => { return Object.assign({}, i, { activity_type : 'bouns', }) }); knex('employees') .insert(modifiedRecords) .then(()=> { /// sent response })Resolví este problema cambiando async.each a async.eachSeries así:
async.eachSeries(records, function(record, next){ saveRecord(record) .then(){ next(null); }); }, function(){ deferred.resolve(); });eachSeries es igual que each pero ejecuta solo una única operación asíncrona a la vez.