Node.js Express - next() 回调

Node.js Express - next() callbacks

在 Node.js Express 中 - 使用 app.use 函数 -

为什么我不必这样做:

app.use(function(req,res,next){
    //do something here
    next(req,res);
});

通常我只是这样做并且它有效

app.use(function(req,res,next){
    //do something here
    next();
});

?

next() 已经知道当前正在执行的请求的 reqres,因此您直接调用它即可。这是专为此请求而创建的独特功能。它还会跟踪您当前在中间件堆栈中的位置,以便调用 next() 执行链中的下一个中间件。

如果您查看 express source code for the router,您实际上可以看到本地定义的 next() 函数,并且可以看到它如何访问一堆闭包定义的变量,其中包括 req, res 和索引计数器,它用于在中间件堆栈和一堆其他变量中前进。因此,它已经可以访问启动下一个中间件调用所需的一切,因此没有理由将这些东西传递给它。

仅供参考,使用开源的一大好处是您可以随时自己查看代码并了解它的作用。

调用next()时,您有多种选择:

  1. 您可以将其调用为 next(),这只会调用堆栈中的下一个中间件处理程序。

  2. 你可以调用它作为 next('route') 它会跳到下一个路由处理程序。

  3. 您可以传递错误 next(err) 并停止所有进一步的中间件或路由器处理,错误处理程序除外。

详细信息记录在此处:http://expressjs.com/guide/error-handling.html

这是该页面的注释:

next() and next(err) are analogous to Promise.resolve() and Promise.reject(). They allow you to signal to Express that this current handler is complete and in what state. next(err) will skip all remaining handlers in the chain except for those that are set up to handle errors as described in the next section.

next 的使用接受一个可选的 Error 对象。如果您不向它传递任何内容,它会假定您已准备好继续处理下一个中间件或实际安装的处理程序。 否则,如果您传递 Error 对象的实例,您将绕过已安装的处理程序(和顺序中间件)并直接转到错误处理程序。

app.use(function (req, res, next) {
  if (!req.user || !req.user.isAuthorized) next(Error('not allowed'))
  else next()
})

app.get('/:user', function (req, res, next) {
  res.render('users/index', { user: req.user })
})

app.use(function (err, req, res, next) {
  console.log(err.message) // not allowed
  res.render('500', err)
})

我试图通过查看 jfriend00 提供的资源来了解内部工作,但不想浪费太多时间来尝试隔离处理回调的特定部分。

所以我尝试了我自己的: jsfiddle

function MW(req, res){
    var req1 = req, res1 = res;
    Array.prototype.shift.apply(arguments);
    Array.prototype.shift.apply(arguments);
    var MWs = arguments;
    console.log(MWs, req1, res1);
    function handle(index){
        if(index ===MWs.length-1){
            return ()=>{MWs[index](req1, res1, ()=>{})};
        }
        return ()=>{MWs[index](req1, res1, handle(index+1))};
    }
    var next = handle(0);
    next();
}

基本上,它使用递归来构建回调链。

然后您可以将其用作 Express use/get/post/put/...:

MW(req, res, 
    (req, res, next)=>{
        console.log("first");
        req.locals = {
            token : 'ok'
        };
        res.canSend =false;
        next();
    },
    (req, res, next)=>{
        console.log("second");
        console.log(req.locals.token, res.canSend);
        next();
    }
);