【问题标题】:cursor.toArray() returns a promise instead of arraycursor.toArray() 返回一个承诺而不是数组
【发布时间】:2017-01-03 14:03:26
【问题描述】:

当前使用节点 4.3.2 和 mongo 2.6。我正在尝试获取整个集合(当前集合中的三个文档)。当我使用这段代码时,我遇到了一个问题。

function checkUpdateTime(last_updated){
    var collection = db.collection(last_updated);
    collection.insert({a:1});
    updateTimes = collection.find({a:1}).toArray();
}
var updateTimes = [];
checkUpdateTime('last_updated');
console.log(updateTimes);

当这段代码是 tun updateTimes 是一个承诺,而不是我希望的数组。目标是编辑数组,然后稍后将其插入集合中。插入语句有效,但文档的检索根本不像我期望的那样操作。我已经尝试了很多版本的这段代码,但没有骰子。

我想归根结底是我想知道为什么要返回一个承诺?

【问题讨论】:

    标签: javascript node.js mongodb promise


    【解决方案1】:

    MongoDB 驱动程序提供了两种处理异步操作的选项:

    • 通过调用者传递的回调
    • 通过向调用者返回一个承诺

    当您不传递回调时,就像您的情况一样,它将返回一个承诺。

    所以你需要在这里做出选择。但是,您无法选择的一个选项是“让这段代码同步运行”

    我更喜欢承诺:

    function checkUpdateTime(last_updated){
      var collection = db.collection(last_updated);
      return collection.insert({ a : 1 }) // also async
                       .then(function() {
                         return collection.find({ a : 1 }).toArray();
                       });
    }
    checkUpdateTime('last_updated').then(function(updateTimes) {
      console.log(updateTimes);
    });
    

    您总是可以更花哨并使用类似Promise.coroutine 的东西,这将使您的代码看起来更同步(即使不是):

    const Promise     = require('bluebird');
    const MongoClient = require('mongodb').MongoClient;
    
    let checkUpdateTime = Promise.coroutine(function* (db, last_updated){
      let collection = db.collection(last_updated);
      yield collection.insert({ a : 1 });
      return yield collection.find({ a : 1 }).toArray();
    });
    
    Promise.coroutine(function *() {
      let db = yield MongoClient.connect('mongodb://localhost/test');
      let updateTimes = yield checkUpdateTime(db, 'foobar');
      console.log(updateTimes);
    })();
    

    async/await,使用Babel

    const MongoClient = require('mongodb').MongoClient;
    
    async function checkUpdateTime(db, last_updated) {
      let collection = db.collection(last_updated);
      await collection.insert({ a : 1 });
      return await collection.find({ a : 1 }).toArray();
    }
    
    (async function() {
      let db = await MongoClient.connect('mongodb://localhost/test');
      let updateTimes = await checkUpdateTime(db, 'foobar');
      console.log(updateTimes);
    })();
    

    【讨论】:

    • "you can't choose"。他可以。与async/await.
    • @vp_arth 仍然不会使其同步(线索在名称中,“异步”;-)。不过,它可能看起来像它,这就是我添加它作为示例的原因:D
    猜你喜欢
    • 2021-04-11
    • 2021-01-13
    • 2019-12-02
    • 2021-01-11
    • 1970-01-01
    • 2015-11-27
    • 2020-01-14
    • 2016-07-22
    相关资源
    最近更新 更多