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数组中,这是我的一部分代码。
问题是, toArray
callback之外的console.log
首先被执行并输出[]
,而toArray
callback中的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 });
希望这可以帮助!