为什么此node.js回调不立即运行? [英] Why does this node.js callback not run immediately?

查看:46
本文介绍了为什么此node.js回调不立即运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 express-generator 会吐出一些错误处理代码,如下所示:

Using the express-generator it spits out some error handling code like this:

app.use('/', routes);
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

在此示例中,如果(由于某种原因)我的路线中断了,或者找不到该路线等,则代码回退以在第二个代码块中抛出404.在第二个代码块(404处理程序)开始执行后,第三个代码块(500处理程序)为什么不立即执行?

In this example, if (for whatever reason) my routes are broken or the route isn't found or whatever, the code falls back to throw a 404 in the second code block. How come the 3rd code block (the 500 handler) doesn't execute immediately after the 2nd code block (the 404 handler) begins executing?

我认为node.js回调的工作方式是该函数开始执行并继续在后台执行,然后下一个回调同时开始执行.但是显然,我对同步回调的工作方式有些困惑.上面的代码是否以某种方式知道在运行500错误处理程序之前要等待"直到404处理程序代码执行完毕?

I thought that the way node.js callbacks work is that the function begins executing and continues to be executed in the background and then the next callback begins executing at the same time. But apparently I am a bit confused by how the synchronous callbacks work. Does the above code somehow know to "wait" until the 404 handler code is done executing before running the 500 error handler?

推荐答案

所有 app.use()语句均在初始化应用程序时运行.他们每个人都设置了一个中间件"处理程序.他们当时实际上并没有运行处理程序,只是将它们注册到Express中间件堆栈中.如果在它们处理页面之前没有处理程序,那么这最后两个 app.use()中间件处理程序将按顺序对请求进行处理,第二个中间件处理程序仅在第一个通过时才能看到请求该请求传递给更多处理程序.

All of the app.use() statements run when your app is initialized. They each set up a "middleware" handler. They don't actually run the handlers at that time, they just register them into the Express middleware stack. If no handler before them handles a page, then these two last app.use() middleware handlers will get a shot at the request in order and the second one only gets to see the request if the first passes the request on to more handlers.

404 处理程序将状态设置为 404 ,然后在中间件堆栈中调用 next()处理程序.最后将是您的最后一个 app.use()语句,该语句将查看是否已设置状态,如果未设置,则将其设置为 500 ,但如果设置,则将其设置为 500 .之前已设置为 404 ,它将保留该设置.然后,它将为缺少的页面应用默认呈现,以显示页面中的状态.

The 404 handler will set the status to 404 and will then call the next() handler in the middleware stack. That will end up being your last app.use() statement which will see if a status has already been set and if not, will set it to 500, but if it was previously set to 404, it will leave it at that. It will then apply a default rendering for a missing page that shows the status in the page.

这是在单个位置应用默认渲染的方法,但在多个位置可能设置错误.

This is a means of having a single place where the default rendering is applied, but multiple places that could set errors.

与异步行为无关.仅当较早的请求处理程序调用 next()时,列表中的下一个请求处理程序才启动.没有等待".您可以使用最后一个 app.use()语句来想到 404 请求处理程序,就像在调用 next()时调用同步函数一样只是说请立即执行链中的下一个请求处理程序(碰巧知道这是为错误状态代码提供默认呈现的处理程序).

None of this really has anything to do with asynchronous behavior. The next request handler in the list is started only when next() is called by an earlier request handler. There is no "waiting". You can think of the 404 request handler using the last app.use() statement like a synchronous function call when it calls next() it is just saying please execute the next request handler in the chain right now (which it happens to know is the one that provides default rendering for the error status code).

回顾一下 app.use()在Express中的工作方式可能会有所帮助.

It might be helpful to review how app.use() works in Express.

每次调用 app.use()都会将请求处理程序添加到列表中.当收到给定的http请求时,Express将从列表中的第一个请求处理程序开始,并检查列表中第一个请求处理程序的参数是否与当前请求匹配(例如,路径是否匹配或在列表中设置的任何其他参数) app.use()语句).如果匹配,则调用该请求处理程序.如果该请求处理程序没有调用 next()来让列表中的下一个请求处理程序有机会处理该请求,则所有处理均已完成,Express假定第一个请求处理程序已完全处理了该请求处理程序.要求.如果此第一个请求处理程序尚未完全处理该请求(例如,它只是在检查标头中的cookie值,并希望继续处理其他处理程序),则它将调用 next().这告诉express查看列表中的下一个 app.use()处理程序,并查看它是否与此请求匹配.

Each call to app.use() adds a request handler to a list. When a given http request comes in, Express starts with the first request handler in the list and checks to see if the parameters of that first request handler in the list match the current request (e.g. does the path match or any other parameters set in the app.use() statement). If it matches, then it calls that request handler. If that request handler does not call next() to let the next request handler in the list have a chance at the request, then all processing is done and Express assumes that the first request handler has completely handled the request. If this first request handler has not completely handled the request (say it was just checking a cookie value in the header and wants processing to continue to other handlers), then it will call next(). This tells express to look at the next app.use() handler in the list and see if it is a match for this request.

只要没有请求处理程序与当前请求匹配,或者没有每个请求处理程序都继续调用 next()来保持链运行,Express就会继续在列表中前进以寻找一些要处理的请求处理程序请求并生成服务器响应.在您的特定示例中,链中倒数第二个请求是 404 处理程序.它假定如果Express处于链的末端,那么还没有处理程序可以处理此请求,因此它必须是对该服务器不旨在处理的页面的请求.因此,它将状态设置为404.然后,由于错误页面的默认呈现在最后一个请求处理程序中,因此它将调用 next()来触发具有以下内容的最后一个默认页面呈现:其中的错误.

As long as no request handler matches the current request or each one that does keeps calling next() to keep the chain going, Express will keep marching down the list looking for some request handler to handle the request and generate a server response. In your specific example, the second to the last request in the chain is a 404 handler. It assumes that if Express got this far down the chain, then no handler has yet handled this request so it must be a request for a page that this server is not designed to handle. Thus, it sets the status to 404. And, then because the default rendering for an error page is in the very last request handler, it calls next() in order to trigger that last default page rendering with the error in it.

这篇关于为什么此node.js回调不立即运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆