nodejs操作express中的next

这次给大家带来nodejs操作express中的next,nodejs操作express中next的注意事项有哪些,下面就是实战案例,一起来看一下。

相信很多人对于nodejs对express中next不是很了解,大多数人不知道其中的next有什么作用,在什么情况下使用,今天文章中就给大家详细介绍下其使用方法,感兴趣的一起来了解下。

最近公司在使用node做前后端分离,采用的web框架是express,所以对express框架进行了深入的了解,前段时间写了篇关于express路由的文章,但是在那篇文章中貌似少了一个很重要的内容,就是express的next,所以今天单独来说说express的next。

关于next主要从三点来进行说明:

next的作用是什么?

我们应该在何时使用next?

next的内部实现机制是什么?

Next的作用

我们在定义express注意事项函数的时候都会将第三个参数定义为next,这个next就是我们今天的主角,next函数主要负责将控制权交给下一个中间件,如果当前中间件没有终结请求,并且next没有被调用,那么请求将被挂起,后边定义的中间件将得不到被执行的机会。

何时使用Next

从上边的描述我们已经知道,next函数主要是用来确保所有注册的中间件被一个接一个的执行,那么我们就应该在所有的中间件中调用next函数,但有一个特例,如果我们定义的中间件终结了本次请求,那就不应该再调用next函数,否则就可能会出问题,我们来看段代码

app.get('/a', function(req, res, next) {  res.send('sucess');  next();});// catch 404 and forward to error handlerapp.use(function(req, res, next) { console.log(404); var err = new Error('Not Found'); err.status = 404; next(err);});app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', {  message: err.message,  error: {} });});

登录后复制

发送请求”/a”,控制台打印日志如下:

404GET /a 500 6.837 ms - -Error: Can't set headers after they are sent.  at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:345:11)

登录后复制

为什么代码会抛异常呢,就是因为我们在res.send之后调用了next函数,虽然我们本次的请求已经被终止,但后边的404中间件依旧会被执行,而后边的中间件试图去向res的headers中添加属性值,所以就会抛出上边的异常。

读到这你可能会有个疑问,如果我不在res.send后边调用next函数,那后边定义的404中间件是不是永远都不会被执行到。现在我们删除res.send后边next函数调用,发送请求”/xxx”,我们就会发现404中间件被执行了,(ㄒoㄒ),这不是和我们之前说的矛盾了吗,我们的自定义中间件没有调用next,但后边定义的中间件仍旧被执行了,这究竟是为什么呢。看来只能求助源码了~~~

Next的内部机制

function next(err) {  ... //此处源码省略  // find next matching layer  var layer;  var match;  var route;  while (match !== true && idx < stack.length) {   layer = stack[idx++];   match = matchLayer(layer, path);   route = layer.route;   if (typeof match !== 'boolean') {    // hold on to layerError    layerError = layerError || match;   }   if (match !== true) {    continue;   }   ... //此处源码省略  } ... //此处源码省略  // this should be done for the layer  if (err) {    layer.handle_error(err, req, res, next);  } else {   layer.handle_request(req, res, next);  } }

登录后复制

上边就是express中next的源码,为了更容易说明问题,对代码进行了删减。从上边的源码可以发现,next函数内部有个注意事项,每次循环都会从stack中拿出一个layer,这个layer中包含了路由和中间件信息,然后就会用layer和请求的path就行匹配,如果匹配成功就会执行layer.handle_request,调用中间件函数。但如果匹配失败,就会循环下一个layer(即中间件)。

现在我们就能解释上边提出的问题了,为什么我们的自定义中间件中没调用next函数,但后边的404中间件仍旧会被执行到,因为我们请求的”/xxx”匹配不到我们注册的”/a”路由中间件,所以while循环会继续往下执行,匹配404中间件成功,所以会执行404中间件。

注意:app.use注册的中间件,如果path参数为空,则默认为”/”,而path为”/”的中间件默认匹配所有的请求。

有一点需要特别指出,其实我们在注意事项中间件的时候函数的第三个参数next和我们定义非路由中间件的函数的第三个参数next不是同一个next,我们在上边看到的是非路由中间件的next,而路由中间件的next函数是这样的

function next(err) {  if (err && err === 'route') {   return done();  }  var layer = stack[idx++];  if (!layer) {   return done(err);  }  if (layer.method && layer.method !== method) {   return next(err);  }  if (err) {   layer.handle_error(err, req, res, next);  } else {   layer.handle_request(req, res, next);  } }

登录后复制

这个next比上边的那个next要简单很多,它负责同一个路由的多个中间件的控制权的传递,并且它会接收一个参数”route”,如果调用next(“route”),则会跳过当前路由的其它中间件,直接将控制权交给下一个路由。

最后有必要再说一说next(err),next(err)是如何将控制权传递到注意事项中间件的,从前边的代码我们知道,当调用next(err)是,express内部会调用layer.handle_error,那我们来看看它的源码

Layer.prototype.handle_error = function handle_error(error, req, res, next) { var fn = this.handle; if (fn.length !== 4) {  // not a standard error handler  return next(error); } try {  fn(error, req, res, next); } catch (err) {  next(err); }};

登录后复制

代码中的fn就是中间件函数,express会对fn的参数个数进行判断,如果参数个数不等于4则认为不是错误处理中间件,则继续调用next(err),这样就会进入到下一个中间件函数,继续进行参数个数判断,如此方式一直到某个中间件注意事项个数是4,就认为找到了错误处理中间件,然后执行此中间件函数。

相信看了本文案例你已经掌握了方法,更多精彩请关注【创想鸟】其它相关文章!

推荐阅读:

注意事项

注意事项

以上就是nodejs操作express中的next的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2770995.html

(0)
上一篇 2025年3月8日 12:46:26
下一篇 2025年3月8日 12:46:31

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • Express Session实现登录验证功能(附代码)

    这次给大家带来Express Session实现登录验证功能(附代码),Express Session实现登录验证功能的注意事项有哪些,下面就是实战案例,一起来看一下。 对于使用Express和Session实现登录验证也是很多人在探求的,…

    编程技术 2025年3月8日
    000
  • JS怎么实现开关效果

    这次给大家带来JS怎么实现开关效果,JS实现开关效果的注意事项有哪些,下面就是实战案例,一起来看一下。 使用JavaScript实现开关效果也是很多人会遇到的操作,这次文章就给大家简单的介绍下方法,感兴趣的一起来看看。 开关灯 html, …

    编程技术 2025年3月8日
    200
  • JS实现图片在网页中被拖拽

    这次给大家带来JS实现图片在网页中被拖拽,JS实现图片在网页中被拖拽的注意事项有哪些,下面就是实战案例,一起来看一下。 Title #pbox{ width: 100%; height:100%; } #box{ width: 200px;…

    编程技术 2025年3月8日
    200
  • JS把list转换成树状结构

    这次给大家带来JS把list转换成树状结构,JS把list转换成树状结构的注意事项有哪些,下面就是实战案例,一起来看一下。 /** * 将list装换成tree * @param {Object} myId 数据主键id * @param …

    编程技术 2025年3月8日
    200
  • js匿名函数传参方法

    这次给大家带来js匿名函数传参方法,js匿名函数传参的注意事项有哪些,下面就是实战案例,一起来看一下。 如下所示: function () { alert(“error”);} //报错:匿名函数不能直接调用 登录后复制 使用 0x01 (…

    编程技术 2025年3月8日
    200
  • JS+H5+canvas绘制图片教程

    这次给大家带来JS+H5+canvas绘制图片教程,JS+H5+canvas绘制图片的注意事项有哪些,下面就是实战案例,一起来看一下。 demo.js window.onload=function() { createcanvas(); d…

    编程技术 2025年3月8日
    200
  • JS实现底部显示新闻并且有滑动特效

    这次给大家带来JS实现底部显示新闻并且有滑动特效,JS实现底部显示新闻并且有滑动特效的注意事项有哪些,下面就是实战案例,一起来看一下。 仿万科的底部的新闻滑动特效 * { padding: 0; margin: 0; } #subject …

    编程技术 2025年3月8日
    200
  • require.js内引入css使用步奏详解

    这次给大家带来require.js内引入css使用步奏详解,require.js内引入css使用的注意事项有哪些,下面就是实战案例,一起来看一下。 在JavaScript的使用中,require.js能提供非常不错的使用效果,这次,文章就重…

    编程技术 2025年3月8日
    200
  • JS数组删除指定元素

    这次给大家带来JS数组删除指定元素,JS数组删除指定元素的注意事项有哪些,下面就是实战案例,一起来看一下。 在大家对JavaScrip的使用中,数组删除特定元素一直是很多人存在的问题,JavaScrip数组怎么去删除特定元素呢?下面文章就给…

    编程技术 2025年3月8日
    200
  • node.js如何实现装饰者模式

    这次给大家带来node.js如何实现装饰者模式,node.js实现装饰者模式的注意事项有哪些,下面就是实战案例,一起来看一下。 装饰者模式的实现更强调类的组合而不是通过继承。这样可以增强灵活性。在node.js 中,可以通过call函数实现…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论