javascript UnhandledPromiseRejectionWarning:TypeError:无法读取属性' forEach'未定义的

时间:2018-06-17 08:53:52

标签: javascript mongodb

我正在使用mongoDB js API这样的代码示例,非常简单的代码示例:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="warp">
<div class="conversation" style="--number: 12px"></div>
<textarea></textarea>
</div>

我试图从localhost上的mongoDB获取文档,然后将该数组传递给每个循环并做一些事情,但是,我得到TypeError:无法读取属性&#39; forEach&#39;未定义,命令的输出如下:

const getAddressFromDB = async () => {
  const MongoClient = require('mongodb').MongoClient;
  const assert = require('assert');

  let res = []
  let num = 0

  // Connection URL
  const url = 'mongodb://localhost:27017';

  // Database Name
  const dbName = 'addr';

  // Use connect method to connect to the server
  MongoClient.connect(url, function(err, client) {
    assert.equal(null, err);
    console.log("Connected correctly to db");

    const db = client.db(dbName);

    findDocuments(db, function(doc) {
      client.close();
      console.log(doc);
      //return doc
      res = doc 
      num = 1
    });
  });

  const findDocuments = function(db, callback) {
    // Get the documents collection
    const collection = db.collection('documents');
    // Find some documents
    collection.find({}).toArray(function(err, docs) {
      assert.equal(err, null);
      //console.log("Found the following records");
      //console.log(docs)
      //docs.forEach(function(element){
      //  address.push(element.address)
      //});
      //res = docs
      callback(docs);
    });
  }


  if(num == 1){
    return res
  }
}

const helper = async() => {
  let addressList = await getAddressFromDB()
  console.log(addressList)
  addressList.forEach(function(element){
    console.log(element)
    console.log("trying "+element.address)
    checkBalanceAndSendTx(element.address,element.privateKey)
  });
}

helper()

有人可以指出为什么我在getAddressFromDB()中得到未定义的数组?我应该从db获取我想要的数组,因为当num为1时我只返回res。

1 个答案:

答案 0 :(得分:2)

等待与 getAddressFromDB 类似的函数时,该函数需要返回一个promise。在您的代码中,您返回undefined,因为您的return语句始终在数据库操作的回调执行完毕之前执行。添加 async 不会改变它。

您可以通过定义一个promise并将其返回来解决此问题(请参阅代码中的注释以获得进一步说明):

// don't call require inside your function, it's common
// practice to do that at the beginning of your module
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');

const getAddressFromDB = () => {

    // async functions need to return a promise,
    // so we create one and and wrap everything in it
    return new Promise(resolve => {
        let res = []
        let num = 0

        // Connection URL
        const url = 'mongodb://localhost:27017';

        // Database Name
        const dbName = 'addr';

        // Use connect method to connect to the server
        MongoClient.connect(url, function (err, client) {
            assert.equal(null, err);
            console.log("Connected correctly to db");

            const db = client.db(dbName);

            findDocuments(db, function (doc) {
                client.close();
                console.log(doc);

                // this makes your promise ultimately resolve
                // with the doc from MongoDB
                resolve(doc);
            });
        });

        const findDocuments = function (db, callback) {
            // Get the documents collection
            const collection = db.collection('documents');
            // Find some documents
            collection.find({}).toArray(function (err, docs) {
                assert.equal(err, null);
                callback(docs);
            });
        }
    });
}

const helper = async () => {
    let addressList = await getAddressFromDB()
    console.log(addressList)
    addressList.forEach(function (element) {
        console.log(element)
        console.log("trying " + element.address)
        checkBalanceAndSendTx(element.address, element.privateKey)
    });
}

helper()