Javascript 排成奇怪的顺序
我会尽量让这件事尽可能简单。下面的函数似乎以一种非常奇怪的方式运行。我从测试打印中得到的输出顺序为1、4、3、2(返回列表为空) 这似乎表明这些代码块内部的代码是最后执行的,您可能会猜到,当我想要返回returnList时,这会产生一些问题Javascript 排成奇怪的顺序,javascript,node.js,mongodb,express,Javascript,Node.js,Mongodb,Express,我会尽量让这件事尽可能简单。下面的函数似乎以一种非常奇怪的方式运行。我从测试打印中得到的输出顺序为1、4、3、2(返回列表为空) 这似乎表明这些代码块内部的代码是最后执行的,您可能会猜到,当我想要返回returnList时,这会产生一些问题 var server = new mongo.Server('localhost', 27017); var db = new mongo.Db('tdp013', server); app.get('/getall', function (req, re
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?这就是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");
});
});
});
});
Node.js本质上是异步的,在单线程事件循环上运行 示例: 假设您已经触发了一个数据库查询,您正在等待查询执行,然后继续,但是在同一时间,不依赖于该数据库查询的代码段将发生什么,它们将不会执行并等待轮到它们 异步与此正好相反。当您执行数据库查询时,Node.js将继续执行代码,当数据库查询完成时,它将返回处理它 因此,在您的示例中,您添加了
console.log(“2”)代码>和控制台日志(“3”)代码>在回调函数中,所以当这些方法执行时,这些行正在执行。和console.log(“4”)代码>不会等待db.open
方法完成。因此结果是1,4,3,2
因此,为了确保returnList
返回正确的数据,必须将其添加到回调方法本身中
希望这将帮助您了解您面临的问题。因为您添加了console.log(“2”)代码>和控制台日志(“3”)代码>在回调函数中,所以当这些方法执行时,这些行正在执行。和console.log(“4”)
不会等待执行db.open
方法。因此结果是1、4、3、2。我想我理解你的意思,我一定没有意识到,即使函数本身也不是同步的。谢谢你的帮助!