callback如何真的在节点js工作

下面是我的代码有两个callback和一个获取路线

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"); }); 

基本上这里的两个callback是error handling。如果我运行该应用程序,并进入localhost:3000/home ,因为没有路由,因为回电不良,得到404错误。

但是,如果我去localhost:3000/login ,它正在显示我的login.html页面,但没有callback被调用。即使没有错误,我的意思是至less它应该在callback中打印第一个控制台消息。但为什么是不要调用callback?

我所读到的关于callback的是,如果你没有指定任何path,它会被调用所有的路由。但是为什么不在这里呢?如果我错了,有人可以抽出时间来阅读这些内容。

这不是关于callback。 它是关于中间件(插件/模块)体系结构如何在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()用于添加要用所有path执行的代码, .get()用于添加要在path匹配时执行的代码。

所以我们现在可以通过遍历数组来处理每个请求到服务器:

 // 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); } } } 

所以这是如何工作的。 当然,中间件是asynchronous的,所以在真正的代码中我们不能使用for循环。 这实际上是next()函数的用途 – 循环链接中间件(如链接列表)(仅链接函数)。 如果没有next()被调用,循环停止。