我会尽量保持这一点。以下函数似乎以一种非常奇怪的方式运行。我从测试打印中得到的输出大约为1,4,3,2(带有一个空的returnList)。
这似乎表明这些代码块内部的代码最后被执行,正如你想的那样,当我想返回returnList时会产生一些问题。
var server = new mongo.Server('localhost', 27017);
var db = new mongo.Db('tdp013', server);
app.get('/getall', function (req, res) {
var returnList = [];
console.log("1");
db.open(function(err, client){
client.collection("messages", function(err, col){
col.find({}, function(err, cursor){
cursor.each(function(err, item){
if(item!=null){
console.log("2");
returnList.push(item);
}
});
console.log("3");
});
});
});
console.log("4");
console.log(returnList);
res.sendStatus(200);
});
我的问题很简单,是否有一个很好的解释(缺少一个更好的词)关于为什么/如何不按书面顺序执行这些行?
或者,有没有办法返回returnList而不在迭代中执行它?
答案 0 :(得分:1)
这只是node.js通过使用JavaScript进一步强化的异步性质。
你试图通过顺序执行(即同步)来阅读这段代码和理由,但这不是它的工作方式。
console.log('1');
db.open(function (err, db) {
// ...
});
console.log('4');
例如,请使用上面的代码段。 你 期望 db.open()
中的函数在继续向控制台写入4
之前完成,但事实并非如此。会发生什么是该节点将异步运行open()
方法并继续执行下一个代码(此处为console.log('4');
)。当open()
方法完成运行时,它将启动参数列表中定义的回调函数。
这是异步JavaScript。你不能指望它在你的编辑器中同步/顺序地运行代码。
开发逻辑将按照您希望它流动的方式流动(它看起来),它必须像下面那样重构:
var server = new mongo.Server('localhost', 27017);
var db = new mongo.Db('tdp013', server);
app.get('/getall', function (req, res) {
var returnList = [];
console.log("1");
db.open(function(err, client){
client.collection("messages", function(err, col){
col.find({}, function(err, cursor){
cursor.each(function(err, item){
if(item!=null){
console.log("3");
returnList.push(item);
}
else {
console.log("4");
console.log(returnList);
res.sendStatus(200);
}
});
console.log("2");
});
});
});
});
答案 1 :(得分:0)
Node.js 本质上是异步的,并且在单线程事件循环上运行。
示例:强> 假设您已经触发了数据库查询,并且您正在等待查询执行然后继续进行,但同时在不依赖于该数据库查询的代码片段中会发生什么,它们将不会执行并等待轮到他们了。
异步与此完全相反。在进行数据库查询时,Node.js将继续执行代码,当数据库查询完成后,它将返回处理它。
因此,在您的情况下,您在回调函数中添加了console.log("2");
和console.log("3");
,因此这些行在执行这些方法时正在执行。并且console.log("4");
不会等待db.open
方法完成。因此结果是1,4,3,2。
所以为了确保returnList
返回正确的数据,你必须在回调方法本身中添加它。
希望这有助于您了解您所面临的问题。