Javascript 排成奇怪的顺序

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

我会尽量让这件事尽可能简单。下面的函数似乎以一种非常奇怪的方式运行。我从测试打印中得到的输出顺序为1、4、3、2(返回列表为空)

这似乎表明这些代码块内部的代码是最后执行的,您可能会猜到,当我想要返回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?

这就是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。我想我理解你的意思,我一定没有意识到,即使函数本身也不是同步的。谢谢你的帮助!