Javascript 回调在NodeJS中究竟是如何工作的
下面是我的代码,它有两个回调和一个get路由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');
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文件名,它将进入底部回调并显示控制台日志..为什么“添加中间件之前添加的路由处理程序不了解中间件”。。原因是什么?我没有查看您正在使用的框架的代码,因此我真的无法告诉您幕后发生了什么。这只是我的直觉。出于这个原因,我还写了一条评论,而不是回答。:)如果你真的对如何异步循环数组感兴趣,我可以将其添加到答案中。目前,我认为上面的伪代码足够好,可以给你一个框架正在做什么的提示。这是一个很好的解释,我想我理解了。如果你分享如何异步循环数组的好例子,会更有帮助。。。