2016-01-04 2 views
3

У меня есть API NodeJS с помощью Express 4. Я использую sequelize для подключения к базе данных, и я вызываю один запрос много раз. Я хочу скопировать результаты в массив. Проблема в том, что res.send не ждет завершения цикла для отправки ответа.асинхронный ответ в цикле в javascript NodeJS

мой код

router.post('/payrollReport/', function(req, res, next) { 
    var usersRecord = []; 
    models.user.findAll(
    ).then(function(users) { 
     for (var i = 0; i < users.length; i++) { 
      models.sequelize.query('SELECT forms.name, COUNT(form_submits.form_id) ' + 
        'FROM form_submits ' + 
        'LEFT JOIN forms ON forms.form_id = form_submits.form_id ' + 
        'WHERE form_submits.user_id = ' + users[i].user_id + 
        'AND date("form_submits"."createdAt") >=' + req.body.begin + 
        'AND date("form_submits"."createdAt") <=' + req.body.end + 
        " GROUP BY forms.name") 
      .then(function(results){ 
       usersRecord.push(results[0]); 
       console.log(usersRecord); 
      });  
     }; 
    }).catch(function(error) { 
     res.status(500).send(error); 
    }); 
    res.send(usersRecord); 
}); 

спасибо за вашу помощь

EDIT

Добавить правильный код, используя Foreach

router.post('/payrollReport/', function(req, res, next) { 
    var usersRecord = []; 
    models.user.findAll(
    ).then(function(users) { 
     async.forEachOf(users, function iterator(user, index, callback) { 
      models.sequelize.query('SELECT forms.name, COUNT(form_submits.form_id) ' + 
        'FROM form_submits ' + 
        'LEFT JOIN forms ON forms.form_id = form_submits.form_id ' + 
        'WHERE form_submits.user_id = ' + user.user_id + 
        'AND date("form_submits"."createdAt") >=' + req.body.begin + 
        'AND date("form_submits"."createdAt") <=' + req.body.end + 
        " GROUP BY forms.name") 
      .then(function(results){ 
       results[0].unshift(user); 
       usersRecord.push(results[0]); 
       callback(); 
      }); 

     }, function (err) { 
      if (err) console.error(err.message); 
      res.send(usersRecord); 
     }); 


    }).catch(function(error) { 
     res.status(500).send(error); 
    }); 

}); 
+0

Тааак ... Ваш вопрос: что? Вероятно, вам нужно будет хранить все ваши обещания в массиве и использовать метод 'Promise.all', чтобы действовать только тогда, когда все ваши обещания были разрешены. – AdamJeffers

+0

вы должны связать свои '.then()' s и не иметь один внутри другого. – Craicerjack

+3

Вы хотите 'Promise.all (users.map (...))'. Читайте http://blog.slaks.net/2015-06-10/advanced-promise-usage/ – SLaks

ответ

5

С Node.js работает асинхронно, ваш res.send(usersRecord); команда выполняется до того, как будут выполнены все итерации. Вы можете использовать async.foreach для этого, это позволит вам запускать вашу отправку только после завершения всех итераций.

Там отличный учебник об этом here

Смежные вопросы