Skip to content

koa-router源码解读 #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
UNDERCOVERj opened this issue Mar 24, 2018 · 0 comments
Open

koa-router源码解读 #6

UNDERCOVERj opened this issue Mar 24, 2018 · 0 comments

Comments

@UNDERCOVERj
Copy link
Owner

先贴一段应用的代码,然后带着代码中的问题去深入

其实,koa-router的源码并不多。

const Koa = require('koa');
const Router = require('koa-router');
const router = new Router();
const app = new Koa();

router.get(path, async (ctx, next) => {})

app.use(router.routes())

发现问题:

  1. 这儿的router.get是怎么做到的呢
  2. router.routes这个中间件有什么用

带着问题去看代码,我的习惯是一个一个function的找

简化一下代码:

class Router {
	constructor () {
		methods.forEach(function (method) {
			Router.prototype[method] = function (name, path, middleware) {
				// ....
				this.register(path, [method], middleware, {
					name: name
				});

				return this;
			};
		});
	}
	register (path, methods, middleware, opts) {
		opts = opts || {};

		var router = this;

		// support array of paths

		// create route
		var route = new Layer(path, methods, middleware, {});
		
		this.stack.push(route);

		return route;
	}
	routes () {
	    return () => {
	        var matched = this.match(ctx.path, ctx.method)
	        // ...
	        return compose(layerChain)(ctx, next)
	    }
	}
	match () {
	    for (var len = layers.length, i = 0; i < len; i++) {
        layer = layers[i];
    
        if (layer.match(path)) {
          matched.path.push(layer);
        }
        return matched;
      }
	}
	
}

解释:

  1. 这里的mothods即包含get,post等已枚举好了的数组
  2. register方法的作用是注册一个route,然后push到stack里,之后再router.routes()调用
  3. Layer是一个用于创建route的类
class Layer {
    constructor (path, methods, middleware, opt) {}
    match () {} // 判断request是否match这个path
    params () {}
}
  1. routes中间件触发后就会将一个个匹配path的middleware触发,期间用了koa-compose。之前已叙述过,这里不再叙述

应用时出现的问题

如果想匹配不支持的url,然后转到404页面,可以直接根据status来跳转

// handle 404 etc.
app.use(async (ctx, next) => {
  try {
    await next()
    if (ctx.status === 404) {
      // do somthing here
    }
  } catch (err) {
    // handle error
  }
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant