NodeJS MongoDB游标toArraycallback函数不会对父范围variables进行更改

MongoClient.connect(dburl, function (err, db) { var collections = []; db.listCollections().toArray(function (err, collInfos) { for (var i = 0; i < collInfos.length; i++) { collections[i] = collInfos[i].name; } console.log(collections); }); console.log(collections); }); 

所以我想把我所有的数据库集合放到一个string数组中,这是我的一部分代码。

问题是, toArraycallback之外的console.log首先被执行并输出[] ,而toArraycallback中的console.log正确地输出数组。

在我看来,有一些范围问题,但我不熟悉NodeJS和MongoDB究竟如何。

这部分代码是asynchronous的:

 db.listCollections().toArray(function (err, collInfos) { for (var i = 0; i < collInfos.length; i++) { collections[i] = collInfos[i].name; } console.log(collections); }); 

所以它会在你第二次调用console.log(collections)之后执行,这就是为什么你首先看到一个空的数组[] ,然后是一个填充的集合列表。 这不是范围问题,而是同步和asynchronous函数调用顺序的混淆。

如果我是你,我会抛弃callback模式,而是使用承诺。 那么你可以做这样的事情:

 var Promise = require('bluebird'); var mongodb = require('mongodb'); var MongoClient = mongodb.MongoClient; var Collection = mongodb.Collection; Promise.promisifyAll(Collection.prototype); Promise.promisifyAll(MongoClient); var client = MongoClient.connectAsync('mongodb://localhost:27017/test') .then(function(db) { return db.collection("myCollection").findOneAsync({ id: 'someId' }) }) .then(function(item) { // Use `item` }) .catch(function(err) { // An error occurred }); 

希望这可以帮助!