node/egg开发记录

作者: 关玮琳linSir | 来源:发表于2018-04-13 13:18 被阅读139次

    node/egg开发记录

    1. 自己实现一个Memcache

    自己手动实现一个Memcache,可以大幅减少查库次数,但是这样可能会加大服务器内存的压力。并且在多实例部署的时候,可能会出现问题,因为可能在不同的实例中,缓存的内容是不一样的,可能返回的值不一样。

    实现思路:维护一个缓存的Map:

    let cacheMap: Map<string, { value: any, lastQueryTime: number }> = new Map();
    

    这样我们,就可以在访问之前,查一下cacheMap,判断数据是否存在,并且查看缓存时间是否有效。

    2. restful风格应用

    做一些业务的后台接口,主要是围绕着增删改查展开的,这个时候我们就可以很好的和restful结合在一起。
    例如:

    • 获取学生信息

    GET /api/student

    • 新增学生信息

    POST /api/student

    • 修改学生信息

    PUT /api/student/123

    • 删除学生信息

    DELETE /api/student/123

    这样我们也可以很好的服用http状态码,例如200,201,204等等。

    这样做的好处就在于,接口定义的简单,方便高效。最重要的一点的是,更看重的是约定,前端后端一定都要遵守这个约定。缺点在于,像一些静态语言,处理起来可能没有动态语言那么方便。

    3. egg/Application

    这个Application是全局应用对象,在一个应用中,只会实例化一次,它继承自Koa.Application,在它上我们可以挂在一些全局的方法和对象。

    在这里面挂载的方法,在编写应用的任何一个地方都可以获取到,例如:Controller,Middleware,Helper,Service 中都可以通过 this.app 访问到 Application 对象。

    在 app.js 中 app 对象会作为第一个参数注入到入口函数中

    // app.js
    module.exports = app => {
      // 使用 app 对象
    };
    

    扩展方式

    框架会把 app/extend/application.js 中定义的对象与 Koa Application 的 prototype 对象进行合并,在应用启动时会基于扩展后的 prototype 生成 app 对象。

    方法扩展

    例如,我们要增加一个 app.foo() 方法:

    // app/extend/application.js
    module.exports = {
      foo(param) {
        // this 就是 app 对象,在其中可以调用 app 上的其他方法,或访问属性
      },
    };
    

    属性扩展

    一般来说属性的计算只需要进行一次,那么一定要实现缓存,否则在多次访问属性时会计算多次,这样会降低应用性能。

    推荐的方式是使用 Symbol + Getter 的模式。

    例如,增加一个 app.bar 属性 Getter:

    // app/extend/application.js
    const BAR = Symbol('Application#bar');
    
    module.exports = {
      get bar() {
        // this 就是 app 对象,在其中可以调用 app 上的其他方法,或访问属性
        if (!this[BAR]) {
          // 实际情况肯定更复杂
          this[BAR] = this.config.xx + this.config.yy;
        }
        return this[BAR];
      },
    };
    

    注: Symbol是一个能确保唯一性的东西,它是在ES6中新引入的内容。

    4. egg/Context

    Context 指的是 Koa 的请求上下文,这是 请求级别 的对象,每次请求生成一个 Context 实例,通常我们也简写成 ctx。在所有的文档中,Context 和 ctx 都是指 Koa 的上下文对象。

    访问方式

    middleware 中 this 就是 ctx,例如 this.cookies.get('foo')。
    controller 有两种写法,类的写法通过 this.ctx,方法的写法直接通过 ctx 入参。
    helper,service 中的 this 指向 helper,service 对象本身,使用 this.ctx 访问 context 对象,例如 this.ctx.cookies.get('foo')。

    扩展方式

    框架会把 app/extend/context.js 中定义的对象与 Koa Context 的 prototype 对象进行合并,在处理请求时会基于扩展后的 prototype 生成 ctx 对象。

    方法扩展

    例如,我们要增加一个 ctx.foo() 方法:

    // app/extend/context.js
    module.exports = {
      foo(param) {
        // this 就是 ctx 对象,在其中可以调用 ctx 上的其他方法,或访问属性
      },
    };
    

    属性扩展

    一般来说属性的计算在同一次请求中只需要进行一次,那么一定要实现缓存,否则在同一次请求中多次访问属性时会计算多次,这样会降低应用性能。

    推荐的方式是使用 Symbol + Getter 的模式。

    例如,增加一个 ctx.bar 属性 Getter:

    // app/extend/context.js
    const BAR = Symbol('Context#bar');
    
    module.exports = {
      get bar() {
        // this 就是 ctx 对象,在其中可以调用 ctx 上的其他方法,或访问属性
        if (!this[BAR]) {
          // 例如,从 header 中获取,实际情况肯定更复杂
          this[BAR] = this.get('x-bar');
        }
        return this[BAR];
      },
    };
    

    5. 利用map进行类型转换

    item.map(o => new MaterialNewsVM(o));
    

    这样的语法,我们便可以把一个item,转成MaterialNewsVM类型。

    6. 利用reduce对数组进行分类

    let defaults = dics.reduce((prev, rule) => {
                    if (rule.key === `revert_by_attention_${account}`) {
                        prev.attention = JSON.parse(rule.value);
                    } else if (rule.key === `revert_by_message_${account}`) {
                        prev.message = JSON.parse(rule.value);
                    }
                    return prev;
                }, {} as {
                    attention: ReplyCacheVM;
                    message: ReplyCacheVM;
                });
    

    相关文章

      网友评论

        本文标题:node/egg开发记录

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