不知道大家有没有用过express.js,有没有这样的疑问:为什么app.use可以一个接一个地添加中间件?connect如何区分正常中间件和错误中间件?中间件处理函数中的next指的是什么?简单看了下connect源码,搞清楚了以上三个问题。为什么app.use可以一个接一个地添加中间件?app.use(functionmiddleware1(req,res,next){//中间件1next();});app.use(functionmiddleware2(req,res,next){//中间件2next();});connect维护了一个中间件栈(middlewarestack)数据结构:栈(stack)每次调用use时,都会向应用(app)实例的栈(stack)中压入一个带有路径和处理函数的对象。源代码:functioncreateServer(){functionapp(req,res,next){app.handle(req,res,next);}//...应用程序堆栈=[];//注意这里returnapp;}proto.use=functionuse(route,fn){varhandle=fn;变种路径=路线;//...//添加中间件this.堆。推({路线:路径,句柄:句柄});返回这个;};connect如何区分正常中间件和错误中间件?//regularmiddlewareapp.use(function(req,res,next){next(newError('boom!'));});//errormiddlewareapp.use(functiononerror(err,req,res,next){//发生错误!});JavaScript函数的长度属性:length。这么说可能比较费解,看看下面的例子就明白了。例如functiontest1(foo,bar){}test.length//2functiontest2(foo,bar,baz){}test.length//3connect区分正常中间件和错误中间件。函数调用(句柄、路由、错误、请求、资源、下一个){vararity=handle。长度;变种错误=错误;varhasError=Boolean(err);try{if(hasError&&arity===4){//错误处理中间件handle(err,req,res,next);返回;}elseif(!hasError&&arity<4){//请求处理中间件handle(req,res,next);返回;}}catch(e){//替换错误error=e;}//continuenext(error);}看了源码,官方文档是这样描述错误处理中间件的,跳过那个中间件上面的任何错误中间件和下面的任何非错误中间件解释其实就是理解:跳过所有前面的错误中间件:索引值递增,请求只走后面的错误中间件,跳过后面的非异常处理中间件:异常中间件满足两个条件,请求会进入,非异常中间件,由于hasError为真,请求不会进入。异常处理中间件只能有一个吗?可以有多个。(官方文档+亲测)app.use(logErrors)app.use(clientErrorHandler)app.use(errorHandler)//错误中间件oneapp.use(functiononerror(err,req,res,next){//发生错误!next(err)//注意这样写,next()不能进入下一个异常处理中间件});//错误中间件twoapp.use(functiononerror(err,req,res,next){//一个错误发生了!});中间件处理函数中的next指的是什么?引用堆栈中的下一个中间件。proto.handle=functionhandle(req,res,out){varindex=0;varstack=this.stack;//...functionnext(err){//下一个回调varlayer=stack[index++];//调用图层句柄call(layer.handle,route,err,req,res,next);}下一个();};从上面代码可以看出,每次调用next()函数,都会执行index++,层是中间件栈中的下一个中间件。其中layer.handle来自this.stack.push({route:path,handle:handle});。期待与您交流,共同进步:微信公众号:哒哒哒前端/excellent_developers前端问答互助星球:t.zsxq.com/yBA2Biq努力成为一名优秀的前端工程师!
