cursor.toArray()返回一个promise而不是array

时间:2016-08-26 20:16:46

标签: javascript node.js mongodb promise

目前使用节点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是一个承诺而不是我希望的数组。目标是编辑数组,然后将其插回到集合中。插入语句有效,但文档的检索根本不会按照我期望的方式运行。我已尝试过这个代码的几个版本,但没有骰子。

我想这可归结为我想知道为什么要退回承诺?

1 个答案:

答案 0 :(得分:10)

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