MongoDB,forEach&承诺:如何知道forEach循环何时完成?

时间:2017-01-15 16:02:27

标签: mongodb foreach promise

为了输出CSV文件,我想从MongoDB集合构建一个数据数组。

我将forEach用于promise,并且我想在读取所有记录后resolve

但是我的代码不起作用。 promise永远不会被解决。似乎if/else条件存在错误。还有另一种方法可以知道forEach循环何时完成?

exports.eachRecord = function () {
  return new Promise(function (resolve, reject) {
    var data = []
    mongoClient.connect(process.env.MONGO, function (err, db) {
      // Handled connection error
      if (err) { return console.log(err) }
      db.collection('log').find().forEach(function (doc) {
        if (doc !== null) {
          console.log(doc.ug)
          data.push(doc.ug)
        } else {
          db.close()
          console.log('done!')
          resolve(data)
        }
      })
    })
  })
}

有什么想法吗? 非常感谢你。

3 个答案:

答案 0 :(得分:1)

您可以使用以下代码:

function getData() {
    return new Promise((resolve, reject) => {

        var data = db.collection('credit_history').find({
            'history.dt': '2019-04-25'
        }).toArray((err, res) => {
            if (err) reject(err);
            resolve(res);
        });
    }).catch((ex)=>{
        console.log(ex);
    });
}

   var array_data =[] ;
        var data = await getData().then((data)=>{
            data.forEach((el)=>{
                console.log(el.p);
                array_data.push(el.p) ;

            })
        });

答案 1 :(得分:0)

forEach是同步的。

问题在于您的mongodb调用,这不是异步的。您可以通过添加回调来使其异步。

db.collection('log').find({}, (err, data) => {
  if (error) ...
  data.forEach((doc) => { ... });
  // Whatever you want to do after forEach.
});

答案 2 :(得分:0)

mongodb自v3.0起支持cursor.forEach(iterator, endCallback)

我们必须区分:

  • array.forEach:它是同步的,并且迭代toArray
  • 之后全部加载到内存中的元素数组
  • mongoCursor.forEach:它是异步的,由mongo驱动程序管理。您正在流式传输数据,因此可以将它们放入文件或http响应中。

因此,要存档您的需求,只需添加一个回调:

    exports.eachRecord = function () {
      return new Promise(function (resolve, reject) {
        const data = []
        mongoClient.connect(process.env.MONGO, function (err, db) {
          if (err) { return reject(err) }

          db.collection('log').find().forEach(
            doc => { data.push(doc.ug) },
            err => {
              if (err) { return reject(err) }
              resolve(data)
            })
        })
      })
    }