前言
Node.js是前端人员步入后台开发的通道。学会了js就基本前后端通吃。但事实真的是这样子的么?
目前虽然说有很多公司在使用Node.js,但是真实应用在生产环境中的项目还是很少。不过已经逐步看到越来越多的传统公司在开始使用Node.js做后台应用了。
错误
错误分两种,一种是操作错误,一种是程序错误。
操作错误
操作错误主要是运行时错误,并不是真正的bug。比如:
- 外部服务无法连接
- 网络不可用
- 请求超时
- 内存溢出
程序错误
就是我们通常意思上说的bug,也就是可以在程序上进行避免的错误。比如:
- 操作一个不存在的对象属性
- 解析一个非法字符串
- 错误的运算
错误处理
由于JavaScrip的弱语言特性,导致JavaScript异常的灵活,有很多的不可控因数在里面。
另外,由于Node.js的异步特性,导致监听也是个问题。
而且最最关键的点,一个地方的错误,会导致整个程序的crash。
所以,在写Node.js程序时,更需要一个可靠,完善的错误处理机制。
这里依旧分别阐述两种不同的错误处理方式。
操作错误处理
操作错误是不可预期的错误,也是无法完全避免的错误。所有我们能做的就是:
- 直接处理这个错误,当然你也可以是忽略,然后继续下一步处理
- 直接把错误打到你的客户端中。
- 重试当前的操作。
- 直接crash掉程序,比如内存溢出就是JavaScript处理不了的。
- 仅仅打印当前的错误日志。
程序错误处理
说到程序错误,那就肯定是我们开发人员的锅了。
本质就是程序写得不健壮。
一般来说,针对程序错误,我们需要额外小心,因为它很可能会导致内存泄露。
如果是没有捕获到的错误,则必须重启应用。
正确的分发错误
写一个程序,特别是一个组件或功能,很多时候你是不知道外部环境的。
当遇到错误时,你所能做到的就是把这个错误分发出去。
那么分发分哪几种呢?
throw
顾名思义就是直接抛出异常,外层通过try,catch来捕获异常。Callbacks
也就是回调函数callback(er, result)
。EventEmitter
事件模型。
需要注意的是
- 如果使用
throw
则一定不能同时使用下面两个分发方式。 Callbacks
和EventEmitter
可以同时存在。EventEmitter
则必须是使用’error’事件发出,且此时监听的事件中必须包含error的事件处理。
那最后一条为什么一定要用error
这个名字的事件呢?原因就是,如果异常不被及时处理很容易导致内存泄露,如果事件名变成error
后,它可以帮你自动抛到最外层的处理函数。这个时候一个uncaught
的进程错误事件就抛出了。具体可以说明可以参考:https://nodejs.org/dist/latest-v4.x/docs/api/events.html#events_error_events
所以,归纳起来,正常的处理应该是这样。
- 首先看有没有错误事件监听,有的话,调用错误事件监听。
- 再则看有没有回调函数,有回调函数则直接转到回调函数。
- 如果以上都没有的话,则直接通过
throw
抛出异常。
最后
很多前端人员,包括我自己,最开始在开发Node.js的程序时,都没有一个严谨的思想,这导致程序写得一点都不健壮,动不动就可能会挂。
我想都是被浏览器给惯坏了,很少会去注意检查变量,检查值是否存在,检测对象是否可用。
所以,在我看来,在开发Node.js的应用过程中,首页需要做的就是确定一个严谨的后台开发理念。然后才是正式的开发。
最后就是,一定要加上日志和各种各样的异常处理。