nodejs模块学习之connect解析

2020-06-17 06:38:57易采站长站整理

return ;

}

// route data

var path = parseUrl(req).pathname || '/' ;

var route = layer.route;

// skip this layer if the route doesn't match

if (path.toLowerCase().substr(0, route.length) !== route.toLowerCase()) {

return next(err); // 执行下一个

}

// skip if route match does not border "/", ".", or end

var c = path[route.length];

if (c !== undefined && '/ ' !== c && ' . ' !== c) {

return next(err); // 执行下一个

}

// trim off the part of the url that matches the route

if (route.length !== 0 && route !== ' / ') {

removed = route;

req.url = protohost + req.url.substr(protohost.length + removed.length);

// ensure leading slash

if (!protohost && req.url[0] !== ' / ') {

req.url = ' /' + req.url;

slashAdded = true ;

}

}

// call the layer handle

call(layer.handle, route, err, req, res, next);

}

next();

};

代码中有相应的注释,可以看出,next 方法就是一个递归调用,不断的对比 route 是否匹配,如果匹配则调用 handle, 如果不匹配,则调用下一个 handle.

call 函数的代码如下:


function call(handle, route, err, req, res, next) {

var arity = handle.length;

var error = err;

var hasError = Boolean(err);

debug( '%s %s : %s' , handle.name || '<anonymous>' , route, req.originalUrl);

try {

if (hasError && arity === 4) {

// error-handling middleware

handle(err, req, res, next);

return ;

} else if (!hasError && arity < 4) {

// request-handling middleware

handle(req, res, next);

return ;

}

} catch (e) {

// replace the error

error = e;

}

// continue

next(error);

}

可以看出一个重点:对错误处理,connect 的要求 是函数必须是 四个参数,而 express 也是如此。如果有错误, 中间件没有一个参数的个数是 4, 就会错误一直传下去,直到后面的  defer(done, err);  进行处理。

还有 app.use 添加中间件:


proto.use = function use(route, fn) {

var handle = fn; // fn 只是一个函数的话 三种接口 // 1. err, req, res, next 2. req, res, 3, req, res, next

var path = route;

// default route to '/'

if ( typeof route !== 'string' ) {

handle = route;

path = '/' ;

}

// wrap sub-apps

if ( typeof handle.handle === 'function' ) { // 自定义中的函数对象