在nodejs sequelize中循环获取异步数据

Posted

技术标签:

【中文标题】在nodejs sequelize中循环获取异步数据【英文标题】:Loop to get asynchronous data in nodejs sequelize 【发布时间】:2016-09-21 22:41:27 【问题描述】:

我正在使用 nodejs 和 sequelize 框架,但我在尝试检索一些数据时遇到问题

getAllMedicamentsWithTotal: function () 
    return medicamentService.getAll().then(function success(medicaments) 
        for(var i = 0 ; i < medicaments.length; i++)
            getTotalMedicament(medicaments[i]).then(function (total) 
                medicaments[i].dataValues.total = total;
            )
        
    , function fail() 

    )

我有这个功能,它可以获取所有药物及其库存总量。但是外部承诺在回调执行之前结束。我知道循环 promise 会出错,但有没有比修复这段代码更好的方法?

为了提供更多上下文,我有一个表库存,它具有表药物的外键,并且在库存表中有药物的数量。我想得到类似 [name1, sum(stockQuantity1), name2, sum(stockQuantity2), ...] 但我无法做到。

如果有任何帮助,我将不胜感激

【问题讨论】:

使用 Promise.all 而不是 for 循环 bluebirdjs.com/docs/api/promise.all.html 所以在外部承诺里面我会放一些类似return Promise.all(...)?的东西。我不确定在发送响应之前会执行回调函数 【参考方案1】:

你必须像这样把所有东西都包装在一个承诺中

getAllMedicamentsWithTotal: function () 
  return new Promise((resolve, reject) => 

    // call your service first
    medicamentService
      .getAll()

      // with your array of results we need to map out an array of promises
      // then feed that array into Promise.all() 
      .then(medicaments => Promise.all(medicaments.map(med => 
        return getTotalMedicament(med);
      ))

      // the result of Promise.all() is an array of results
      // reduce the totals to get your accumulated total and resolve it to the caller
      .then(arrayWithTotals => 
        let total = arrayWithTotals.reduce((acc, obj) => acc += obj.dataValues.total, 0);
        resolve(total);
      );
  );

// elsewhere...

getAllMedicamentsWithTotal().then(total =>  /** your total */ );

顺便说一句,您似乎正在为最有可能通过join 查询完成的事情做很多逻辑。 IIRC 续集将此称为include property on your query object.

【讨论】:

我发现做一个简单的 group by 可以解决问题......我仍然对 group by 和 join 有错误,但这是一个单独的问题,感谢这个答案

以上是关于在nodejs sequelize中循环获取异步数据的主要内容,如果未能解决你的问题,请参考以下文章

nodejs sequelize连接字符串中的异步等待问题

使用 sequelize 和 nodejs 更新多条记录?

Node JS、Socket.io、异步和阻塞事件循环

NodeJS,如何强制异步 for 循环在传递到下一次迭代之前等待 HTTP 请求解决,这样我们就不会收到 EMFILE 错误?

在nodejs(异步)中寻找循环和回调的正确模式

JavaScript异步处理问题,循环处理异步任务,并拿到数据,Nodejs循环异步任务接口处理