乐趣区

关于node.js:Node学习Kao框架

1. 简介

koa 框架是一个遵循洋葱模型的轻量级的 nodejs 框架,将大部分工作都抛给中间件来解决,框架只专一于 compose 各个中间件,并依照 use 注册的程序一一执行中间件。

2. 装置应用

装置:npm install koa -s
应用:

const Koa = require('koa');
const app = new Koa;
app.listen(3000);

3. 中间件的应用

const Koa  = require('koa');
const mount = require('koa-mount');

const app = new Koa();
app.use(mount('/api', function() {.....}));
app.listen(80);

以上代码应用了 koa-mount 来进行进行路由解决,应用 koa 实例上的 use 办法将 mount 函数返回的函数注册为中间件。以下是 koa 中 use 函数。

  use(fn) {if (typeof fn !== 'function') throw new TypeError('middleware must be a function!');
    if (isGeneratorFunction(fn)) {
      deprecate('Support for generators will be removed in v3.' +
                'See the documentation for examples of how to convert old middleware' +
                'https://github.com/koajs/koa/blob/master/docs/migration.md');
      fn = convert(fn);
    }
    debug('use %s', fn._name || fn.name || '-');
    this.middleware.push(fn);
    return this;
  }

能够看到,一个函数中间件在 use 函数中先是判断是否为 generator 函数,如果是,应用 koa-convert 转换,最终都会放入 koa 实例的 middleware 数组中保留,供后续调用。
a. 说一下 isGeneratorFunction 函数,这个函数的思路是通过 Function 动态创建一个 generate 函数,而后取其原型与传入的函数的原型比照,如果雷同阐明传入函数就是 generate 函数。
b. 再说一下 convert 函数,这个函数在 koa-convert 包中,就是外部又引入了 co 库,将传入的 generate 函数包裹,达到自执行的成果。

回过头说一下 koa 的 listen 函数,代码如下:

  listen(...args) {debug('listen');
    const server = http.createServer(this.callback());
    return server.listen(...args);
  }

  callback() {const fn = compose(this.middleware);

    if (!this.listenerCount('error')) this.on('error', this.onerror);

    const handleRequest = (req, res) => {const ctx = this.createContext(req, res);
      return this.handleRequest(ctx, fn);
    };

    return handleRequest;
  }

能够看到,listen 函数外部调用了 node 外围模块 http,创立了一个 http 服务,并将本身的 callback 函数作为 http 服务的响应函数。
而 callback 函数外部则是通过 compose 将之前注册的中间件包裹,而后通过 createContext 将 req 和 res 封装到一个 ctx 中,逐层传入前面的中间件中。ctx 内容如下:

4.request 和 response 解决

如上所示,req 和 res 被封装到了 context 中,在各个中间件都能够从参数中失去,中间件能够拿到两个参数:一个是 context,各中间件能够通过它来进行通信和同步状态;第二个是 next,调用它会执行后续中间件。应用示例如下:

const Koa = require('koa')
const app = new Koa()
// 申明一个 main 中间件,如果你急于理解中间件能够跳转到(三)const main = (ctx,next) =>{if (ctx.request.accepts('json')) {
    ctx.response.type = 'json';
    ctx.response.body = {data: 'Hello World'};
  } else if (ctx.request.accepts('html')) {
    ctx.response.type = 'html';
    ctx.response.body = '<p>Hello World</p>';
  } else if (ctx.request.accepts('xml')) {
    ctx.response.type = 'xml';
    ctx.response.body = '<data>Hello World</data>';
  } else{
    ctx.response.type = 'text';
    ctx.response.body = 'Hello World';
  };
}; // 间接运行页面中会显示 json 格局,因为咱们没有设置申请头,所以每一种格局都是 ok 的。app.use(main)//app.use()用来加载中间件。app.listen(3000)

能够看到,咱们给返回数据赋值能够间接应用’=‘赋值,在 koa 的 response 中 body 通过 set 属性,将设置进来的 body 值依照其 type 进行解决,如下。

  set body(val) {
    const original = this._body;
    this._body = val;

    // no content
    if (null == val) {if (!statuses.empty[this.status]) this.status = 204;
      if (val === null) this._explicitNullBody = true;
      this.remove('Content-Type');
      this.remove('Content-Length');
      this.remove('Transfer-Encoding');
      return;
    }

    // set the status
    if (!this._explicitStatus) this.status = 200;

    // set the content-type only if not yet set
    const setType = !this.has('Content-Type');

    // string
    if ('string' === typeof val) {if (setType) this.type = /^\s*</.test(val) ? 'html' : 'text';
      this.length = Buffer.byteLength(val);
      return;
    }

    // buffer
    if (Buffer.isBuffer(val)) {if (setType) this.type = 'bin';
      this.length = val.length;
      return;
    }

    // stream
    if (val instanceof Stream) {onFinish(this.res, destroy.bind(null, val));
      if (original != val) {val.once('error', err => this.ctx.onerror(err));
        // overwriting
        if (null != original) this.remove('Content-Length');
      }

      if (setType) this.type = 'bin';
      return;
    }

    // json
    this.remove('Content-Length');
    this.type = 'json';
  },

5. 动态资源

应用 koa-static 中间件来解决动态资源,实例如下:
装置 npm: npm install koa-static
应用:

const Koa = require('koa');
const app = new Koa();
const path = require('path');
const serve = require('koa-static');

const main = serve(path.join(__dirname));

app.use(main);
app.listen(3000);

参考资料:

https://zhuanlan.zhihu.com/p/67239164?utm_id=0

退出移动版