绝大多数对Node.js的讨论都把关注点放在了其处理高并发的能力上。简单来说,相比其他同类解决方法,Node框架给开发这提供了构建高性能网络应用的强大能力,当然,开发者要明白Node内部所作出的权衡,以及Node构建应用之所以性能好的原因。
Node.js为JavaScript引入了一个复杂的概念:共享状态的并发。
因为Node采用一个长期运行的进程,每个请求共享这个进程,当这个变量被回调函数修改之后,结果就会改变。如PHP的Apache会产生出多个线程(每个请求对应一个线程),每次都会刷新,内部变量等就会重新赋值。所以对回调函数修改当前内存中的变量一定要非常小心,还要注意对错误的处理是否会潜在的修改这些状态。
阻塞和非阻塞
当ajax同步处理的时候,必须等待服务器响应并返回页面,才执行后续语句,这就是阻塞。Node.js采用了事件的轮询,事件轮询是非阻塞的。
什么是事件的轮询,Node会注册一个事件,挂到任务队列中,然后不断的询问内核事件是否分发,当事件分发之后,就会触发该事件的回调函数,然后继续执行下去,如果没有分发,就会继续执行后续的语句。
console.log('hello'); setTimeout(function(){ console.log('world'); }, 500); console.log('bye'); //输出 //hello //bye //world
单线程
如果想了解更多的运行机制,单线程,看大佬的文章:http://www.ruanyifeng.com/blog/2014/10/event-loop.html
错误处理
一个Http请求中,如果某个回调函数发生错误,整个进程都会遭殃,因为错误没有被捕获,进程的状态就不确定。之后就可能无法正常工作,并且如果错误始终不处理的化,就会一直抛出意料之外的错误,这样很难调试。
为什么try/catch 不会捕获异常呢,因为异步机制,当异步时,catch代码块已经执行过后,异步的代码才开始执行,一但出现错误,就不会被捕获到。这时候就会触发uncaughtException事件,直接终止当前栈,结果会导致所有用户终止连接。
处理方法参考:http://www.infoq.com/cn/articles/quit-scheme-of-node-uncaughtexception-emergence/
绝大部分Node异步API接受回调函数,第一个参数都是错误对象或者null;