NodeJs 笔记杂谈
Node异步编程难点:
1. 异常处理 不能仅仅依靠传统的try/catch/final语句块进行异常捕获;而是应采用回调函数调用时传err错误码参数的方式捕获异常; 原则1:必须执行调用者传入的回调函数,回调函数第一个参数是err,err为真,则有异常,则可执行异常后续处理,否则执行相应的正常操作。 原则2:正确传递回异常供调用者判断,即在编写异步方法时,只要将异常正确传递给用户的回调方法即可,其他不作过多处理。
2. 函数嵌套过深 不同于前端开发,后端开发可能存在一些业务逻辑相互依赖,多个事件协作完成的任务的场景,因而可能存在多层次的嵌套异步调用的问题。 3. 阻塞代码 Node未提供诸如sleep的方法而只是setInterval/setTimeout函数,不可通过while模拟sleep占用CPU的时间资源, 对于此情况,在统一规划业务逻辑之后,调用 setTimeout() 的效果更好。 4. 多线程编程 Node通常是单线程执行JavaScript代码(Node相对浏览器没有UI渲染过程),不能充分利用多核CPU, 而浏览器提出的Web Workers可将JavaScript执行与UI渲染分离,由主线程传递消息给其他工作线程有效减少CPU和UI渲染问题, Node的child_process模块作为基础API,cluster模块是更深层次的应用。 5. 异步转同步 Node提供了大部分异步API和少量的同步API,对于某些同步操作需求,若Node没有提供原生支持,则需借助三方库或重新修改代码编译等方式来实现, 然而对于异步调用,通过良好的控制流程,也可将逻辑梳理为顺序的形式。 异步编程难点对应的一些解决方案:
1. 事件发布/订阅模式 不同于前端存在事件冒泡以及多个控制事件传递的方法,而Node提供了events模块比较简单,也可实现事件订阅和发布操作,以及其他如once、on、emit等事件方法。 使得事件与具体的逻辑处理很好的关联与解耦。 几点注意: 1. 订阅者或者侦听器对象不可过多,过多可能存在一些内存泄漏以及在轮询执行所有侦听器时占用过多的CPU资源和时间,可调用setMaxListeners(0)移除警告 或者调高阈值。 2. 针对error事件,EventEmitter对象对该事件特殊处理,若该error有对应的侦听器对象,则执行之,否则则抛出异常,可能引起进程退出。 故而最好需要处理error事件增强健壮性。 继承events模块: var events = require('events'); function SomeEventEmitter() { events.EventEmitter.call(this); } util.inherits(SomeEventEmitter, events.EventEmitter); 2. 利用事件队列解决雪崩问题 雪崩问题:高访问量、大并发的情况下内存的缓存失效的情景,此时大量请求同时涌入数据库,数据库无法同时承受如此大的查询请求,进而往前影响到网站的整体的响应速度。