美文网首页
koa-router笔记

koa-router笔记

作者: 我叫Aliya但是被占用了 | 来源:发表于2019-07-16 23:12 被阅读0次

基于koa,有自己的next(洋葱模型),有点像发布订阅

用法(npmjs官网

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

router.get('/', (ctx, next) => {
  console.log(222)
  ctx.body = 'ok'
  setTimeout(()=> next(), 2000)
})
router.get('/', (ctx, next) => {
  console.log(333)
  setTimeout(()=> next(), 1000)
})
router.get('/login', (ctx, next) => {
  ctx.body = 'ok'
  next()
})
router.get('/user/:id', (ctx, next) => {
  console.log(ctx.params, ctx.query)
  ctx.body = 'ok'
  next()
})
app.use(router.routes()).use(router.allowedMethods())
app.use(async (ctx, next) => {
  console.log('access by ', ctx.url)
})

app.listen('3000')

实现

/** my router */
class Layer {
    constructor (method, path, fn) {
        this.regexp = new RegExp('^' + path.replace(/:([^/]+)/g, '([^/?#]+)') + '$')
        this.params_keys = path.match(/:([^/]+)/g)

        this.method = method;
        this.path = path
        this.fn = fn
    }
    
    match (method, path) {
        let vals = path.match(this.regexp)
        if (this.method == method && vals) {
            // 处理params参数
            let params = {}
            this.params_keys && this.params_keys.forEach((item, index) => {
                params[item.substr(1)] = vals[index+1]
            });
            return { is_match: true, params }
        }
        return { is_match: false }
    }
}
class Router {
    constructor () {
        this.middlewares = []
    }

    get (path, fn) {
        this.middlewares.push(new Layer('GET', path, fn))
    }

    post (path, fn) {
        this.middlewares.push(new Layer('POST', path, fn))
    }

    routes () {
        return (ctx, next) => {
            let match_router = this.middlewares.filter(middle => {
                let result = middle.match(ctx.method, ctx.url)
                if (result.is_match) {
                    ctx.params = result.params
                }
                return result.is_match
            })
            // 以中间件方式执行路由方法
            match_router.reduceRight((prev, next) => {
                return async () => {
                    if (prev.is_called == 'yes') { 
                        throw new Error('next 只能调用一次')
                    }
                    prev.is_called = 'yes'
                    return await next.fn(ctx, prev)
                }
            }, next)()
        }
    }

    allowedMethods () {
        return (ctx, next) => {
            next()
        }
    }
}
module.exports = Router

二级路由

// sub.js
let Router = require('../koa-router')
let router = new Router()

router.prefix('/sub')
router.get('/prat1', async (ctx, next) => {
    ctx.body = 'wrong! guess again'
    await next()
})

module.exports = router
// app.js
……
let sub_route = require('./routes/sub')
……
app.use(sub_route.routes(), sub_route.allowedMethods())
……

实现

/** my router */
class Layer {
    constructor (method, path, fn) {
        this.regexp = new RegExp('^' + path.replace(/:([^/]+)/g, '([^/?#]+)') + '$')
        this.params_keys = path.match(/:([^/]+)/g)

        this.method = method;
        this.path = path
        this.fn = fn
    }
    
    match (method, path, root) {
        if (root && path.startsWith(root)) {
            path = path.substr(root.length)
        }
        let vals = path.match(this.regexp)
        if (this.method == method && vals) {
            // 处理params参数
            let params = {}
            this.params_keys && this.params_keys.forEach((item, index) => {
                params[item.substr(1)] = vals[index+1]
            });
            return { is_match: true, params }
        }
        return { is_match: false }
    }
}
class Router {
    constructor () {
        this.middlewares = []
        this.root = null
    }

    prefix (root) {
        this.root = root
    }

    get (path, fn) {
        this.middlewares.push(new Layer('GET', path, fn))
    }

    post (path, fn) {
        this.middlewares.push(new Layer('POST', path, fn))
    }

    routes () {
        return (ctx, next) => {
            let match_router = this.middlewares.filter(middle => {
                let result = middle.match(ctx.method, ctx.url, this.root)
                if (result.is_match) {
                    ctx.params = result.params
                }
                return result.is_match
            })
            // 以中间件方式执行路由方法
            match_router.reduceRight((prev, next) => {
                return async () => {
                    if (prev.is_called == 'yes') { 
                        throw new Error('next 只能调用一次')
                    }
                    prev.is_called = 'yes'
                    return await next.fn(ctx, prev)
                }
            }, next)()
        }
    }

    allowedMethods () {
        return (ctx, next) => {
            next()
        }
    }
}
module.exports = Router

相关文章

  • koa-router笔记

    基于koa,有自己的next(洋葱模型),有点像发布订阅 用法(npmjs官网) 实现 二级路由 实现

  • koa-router处理URL

    koa-router处理URL koa-router使用的结构const Koa = require('koa')...

  • 2019-02-11 koa-router使用指南

    koa-router文档地址 https://www.npmjs.com/package/koa-router 使...

  • 5. koa-router 路由中间件

    安装koa-router模块:https://www.npmjs.com/package/koa-router 1...

  • koa-router使用指南

    koa-router文档地址https://www.npmjs.com/package/koa-router ge...

  • koa

    koa 学习 中间件 koa-router koa-router 获取get/post请求参数 koa-bodyp...

  • koa-router中间件

    1 .安装koa-router中间件 2 .最基本的koa-router的写法 3 .层级

  • Koa和Nunjucks的API使用总结

    一、Koa的使用: 二、Koa-router处理不同URL 三、Nunjucks的使用 四、Koa-router框...

  • 路由

    一、Koa 路由 1.安装koa-router cnpm install koa-router -S 2.一个简单...

  • node 中间件 koa-router

    koa-router中间件的基本使用 1.安装npm install --save koa-router 2.实例...

网友评论

      本文标题:koa-router笔记

      本文链接:https://www.haomeiwen.com/subject/onoxlctx.html