以下是文件tags.js
的内容。
//the following initializes the MongoDB library for Javascript.
var MongoClient = require('mongodb').MongoClient,
assert = require('assert');
//connection URL
abc = 'mongodb://localhost:27017/abcbase/
/* the following is a global variable
where I want retrieved content */
var arrayToReturn = [];
/* toFind is a dictionary, toSearch is a
MongoDB collection (input is its name as a string) */
function findElemHelper(toSearch, toFind) {
/* establishes connection to the database abcbase
and runs the contents of the function that is
the second input */
MongoClient.connect(abc, function(err, db) {
/* coll is the collection being searched.
tempCurs is the results of the search returned
as a cursor
*/
coll = db.collection(toSearch);
tempCurs = coll.find(toFind);
/* the three lines below this comment
form the crux of my problem. I expect
arrayToReturn to be assigned to docs
(the contents of the cursor received by
the find function). Instead it seems like
it is declaring a new variable in local scope.*/
tempCurs.toArray(function(err, docs) {
arrayToReturn = docs;
});
});
}
function findElem(toSearch, toFind) {
findElemHelper(toSearch, toFind);
return arrayToReturn;
}
function returnF() {
return arrayToReturn;
}
var ln = findElem("userCollection", {});
var lm = returnF();
console.log(ln);
console.log(lm);
当我使用命令node tags.js
的节点解释器运行文件时,它会打印
[]
[]
当我在节点解释器上运行相同的代码(我从终端输入命令node
并将相同的代码复制粘贴到shell中)时,console.log(ln)
打印[]
}和console.log(lm)
打印我想从MongoDB中检索的文档的内容。
有人可以解释这种行为吗?
答案 0 :(得分:1)
正如一些评论者指出的那样,问题是findElemHelper
方法的异步性质。其中一条评论中发布的long, but detailed answer解释了javascript中异步的基础知识以及如何处理这种编码风格。
简而言之,对于异步代码,您不能假设操作顺序与代码中的语句相同。您在确定问题难题的位置时是正确的,但问题不在于范围,而是在数据库返回数据时调用传递给tempCurs.toArray
的函数,这可能是在其余的数据之后。文件已完成执行。 (传递到MongoClient.connect
的函数也是如此,在db甚至连接之前你最终可能会调用console.log
!)
以下是我们如何使用回调来解决问题,目标是构建我们的代码,以确保数据库在调用console.log
之前已经返回数据:
var MongoClient = require('mongodb').MongoClient;
var abc = 'mongodb://localhost:27017/abcbase/';
/**
* Take a callback function as the last parameter which will
* be called when the array is retrieved.
*/
function findElem(toSearch, toFind, callback) {
MongoClient.connect(abc, function(err, db) {
var coll = db.collection(toSearch);
var tempCurs = coll.find(toFind);
tempCurs.toArray(callback);
});
}
findElem("userCollection", {}, function(err, docs) {
console.log(docs);
});
答案 1 :(得分:0)
你的函数findElemHelper使用回调对MongoDB进行异步调用。因此,您不知道arrayToReturn何时填充其内容。机会是,在控制台中打印lm意味着你给了它足够的时间来实际填充。
您应该尝试重构代码,以便可以在回调中使用异步调用的响应,而不是在全局变量外部。