异步响应到javascript NodeJS中的循环

Posted

技术标签:

【中文标题】异步响应到javascript NodeJS中的循环【英文标题】:asynchronous response into a loop in javascript NodeJS 【发布时间】:2016-04-08 08:37:15 【问题描述】:

我有一个使用 Express 4 的 NodeJS API。我正在使用 sequelize 连接到数据库,并多次调用一个查询。我想将结果累积到一个数组中。问题是res.send 没有等待循环结束来发送答案。

我的代码

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);
);

感谢您的帮助

编辑

使用 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);
    );  

);

【问题讨论】:

Soooo...你的问题是什么?您可能需要将所有 Promisable 存储到一个数组中并使用 Promise.all 方法,以便仅在您的所有 Promise 都已解决时才采取行动。 你应该链接你的.then(),而不是在另一个里面。 你想要Promise.all(users.map(...))。阅读blog.slaks.net/2015-06-10/advanced-promise-usage 【参考方案1】:

由于 node.js 是异步工作的,所以您的 res.send(usersRecord); 命令会在所有迭代完成之前执行。您可以为此使用async.foreach,它只允许您在所有迭代完成后运行您的发送。

有一个很棒的教程here

【讨论】:

以上是关于异步响应到javascript NodeJS中的循环的主要内容,如果未能解决你的问题,请参考以下文章

如何在多个异步调用中向 NodeJS 中的数据库发送响应?

Nodejs中异步函数的返回值

nodejs使用经验总结

NodeJS异步队列太快(减慢异步队列方法)

带有异步请求的 NodeJS

确认响应发送太晚; NodeJS Express 异步响应