koa关键点

洋葱模型

koa的洋葱模型

  • 关注koa-compose
/**
   * @param {Object} context
   * @return {Promise}
   * @api public
   */

  return function (context, next) {
    // last called middleware #
    let index = -1
    return dispatch(0)
    function dispatch (i) {
      if (i <= index) return Promise.reject(new Error('next() called multiple times'))
      index = i
      let fn = middleware[i]
      if (i === middleware.length) fn = next
      if (!fn) return Promise.resolve()
      try {
        return Promise.resolve(fn(context, dispatch.bind(null, i + 1)))
      } catch (err) {
        return Promise.reject(err)
      }
    }
  }

异常处理

  • 关注koa/lib/application.jscallbackhandleRequest两个函数
  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;
  }
  
  handleRequest(ctx, fnMiddleware) {
    const res = ctx.res;
    res.statusCode = 404;
    const onerror = err => ctx.onerror(err);
    const handleResponse = () => respond(ctx);
    onFinished(res, onerror);
    return fnMiddleware(ctx).then(handleResponse).catch(onerror);
  }
  • ctx.onerror(err) => this.on(‘error’, this.onerror).
  • koa-onerror重写了context.onerror函数

CO

  • 基于Generator语法实现的库:用同步方式写异步逻辑,即async/await的效果
    	const co = require('co');
    	const promise = co(function* () {
    		const res1 = yield 123;
    		const res2 = yield 456;
    		return res1 + res2;
    	});
    	promise.then(val => {
    	
    	}).catch(err => {
    		...
    	})
    
    • ① 如何像async/await调用函数后自动执行
    • ② 如何把yield expression的expression执行结果返回给res1、res2?
    • 图片来源
      在这里插入图片描述

委托模式

外部对象接受到的操作委托内部属性进行处理——可直接访问context.query、context.method等操作,实际上它是在context.request对象上的

  • accessfluent方法的差异 :setter时fluent可以链式调用
    	const delegate = require('delegates');
    	
    	const request = {
    	  query: 18,
    	};
    	const response = {
    	  body: '18',
    	};
    	const context = {
    	  request,
    	  response
    	};
    	
    	delegate(proto, 'request')
    	  .fluent('query')
    	// getter
    	const req = proto.query();
    	// setter (chainable)
    	proto
    	  .query({ a: 1 })
    	  .query({ b: 2 });
    	
    	delegate(proto, 'response')
    	  .access('body')
    	// getter
    	const res = proto.body;
    	// setter
    	console.log(proto.body = 'set-body');
    
  • 通过 defineGetterdefineSetter 分别设置 getter 和 setter:传递的函数的内部 this 指向原来的属性
    	let a = { nickName: 'HotDog' }
    	a.__defineGetter__('name', function() {
    	  return this.nickName // 此处 this 仍然指向 a
    	})
    

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值