Javascript 回调在NodeJS中究竟是如何工作的

Javascript 回调在NodeJS中究竟是如何工作的,javascript,node.js,meteor,callback,Javascript,Node.js,Meteor,Callback,下面是我的代码,它有两个回调和一个get路由 app.get('/login', function(req, res, next) { res.sendFile(__dirname + '/public/views/login.html'); }); app.use(function (req, res, next) { console.log("first callback 1"); var err = new Error('Not Found');

下面是我的代码,它有两个回调和一个get路由

app.get('/login', function(req, res, next) {
     res.sendFile(__dirname + '/public/views/login.html');
});
app.use(function (req, res, next) {
      console.log("first callback 1");
      var err = new Error('Not Found');
      err.status = 404;
      next(err);
      console.log("first callback 2");
});
app.use(function (err, req, res, next) {
   // set locals, only providing error in development
      console.log("second callback");
      res.locals.message = err.message;
      res.locals.error = req.app.get('env') === 'development' ? err : {};
  // render the error page
     res.status(err.status || 500);
     res.render('error');
     console.log("error send");
});
这里的两个回调基本上是用于错误处理的。如果我运行应用程序并转到
localhost:3000/home
,因为没有路由,而且由于回调,我会得到404错误

但如果我转到
localhost:3000/login
,它会显示我的login.html页面,但不会调用任何回调。即使没有错误,我的意思是它至少应该打印回调中的第一条控制台消息。但为什么它不调用回调


我读到的关于回调的内容是,如果你不指定任何路径,所有路由都会调用它。但为什么不在这里呢?有人能花点时间读一下这篇文章,如果我错了,帮我澄清一下吗

这与回调无关。这是关于中间件(插件/模块)体系结构在Express中的工作方式(顺便说一句,还有许多其他框架,但请注意:并非所有框架都是这样工作的)

Express实现的真正代码是模块化的,有点复杂,但基本上是这样工作的:

var middlewares = [];

var app = {
    use: function (callback) {
        middlewares.push({path:"", callback: callback});
    },
    get: function (path, callback) {
        middlewares.push({path: path, callback: callback});
    }
}
你看,这个想法很简单。真的没有什么花哨的
.use()
用于添加要在所有路径中执行的代码,而
.get()
用于添加要在路径匹配时执行的代码

因此,我们现在可以通过在阵列中循环来处理对服务器的每个请求:

// WARNING: NOT REAL CODE, this is only meant as an illustration

function processRequest (req, res) {
    for (var i=0; i<middlewares.length; i++) {
        var whatToDo = middlewares[i];

        if (whatToDo.path == "") { // no need to check path
            whatToDo.callback(err, req, res, next);
        }
        else if (whatToDo.path == req.path) { // check if path match
            whatToDo.callback(req, res, next);
        }
    }
}
//警告:不是真正的代码,这只是一个说明
函数processRequest(req、res){

对于(var i=0;iYou可能希望尝试将您的
app.get('/login'…)
到底。@AlexPánek现在得到了。但这意味着什么..应该为所有路由调用回调..但为什么它在底部时没有被调用..你能帮我理解一下吗?我不知道具体细节,但似乎在添加中间件之前添加了任何路由处理程序(
app.get
)(
app.use
)不知道中间件。@AlexPánek.ok..但是如果我在顶部和res.sendFile中有app.get('/login'..),我会给出一个不存在的html文件名,它将进入底部回调并显示控制台日志..为什么“添加中间件之前添加的路由处理程序不了解中间件”。。原因是什么?我没有查看您正在使用的框架的代码,因此我真的无法告诉您幕后发生了什么。这只是我的直觉。出于这个原因,我还写了一条评论,而不是回答。:)如果你真的对如何异步循环数组感兴趣,我可以将其添加到答案中。目前,我认为上面的伪代码足够好,可以给你一个框架正在做什么的提示。这是一个很好的解释,我想我理解了。如果你分享如何异步循环数组的好例子,会更有帮助。。。