接触Node,提得最多的可能就是回调,异步非阻塞处理,思前想后,JavaScript从前端语言过渡到服务器端,最大的劣势可能就是线程,固然这方面的不足如今也被慢慢弥补起来了(不少第三方的npm包可供下载),而在初期时,其语言的执行思想也是偏向多线程的,因而用了一个很是巧妙的方法:事件驱动。javascript
Node.Js使用事件驱动模型,当web server接收到请求,就把它关闭而后进行处理,而后去服务下一个web请求。当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。这个模型很是高效可扩展性很是强,由于webserver一直接受请求而不等待任何读写操做。(这也被称之为非阻塞式IO或者事件驱动IO)前端
这边引用以前看过的一篇博客上的图及setTimeout的说明java
这边就要借用setTimeout()函数来讲明Node的事件驱动机制,首先运行下面一段函数node
console.log("aaaa"); for(i=1;i<3;i++){ setTimeout(function(){console.log(i)},0) } console.log("bbbb");
运行结果:web
比较怪异的是console完aaaa以后并无当即console setTimeout里的函数,固然若是这里去掉setTimeout改成console结果仍是会如咱们想象的同样,固然咱们要讲的是事件驱动,因此这边用一个setTimeout(fuc,0)来表示当即执行。而咱们看到了setTimeout执行落在了正常事件的最后,以前看的一篇博客,博主写的是setTimeout函数若是置零,也不会当即执行,由于HTML5默认规范对于setTimeout函数有2ms的延迟,那会不会是由于这2ms的延迟导致输出延时了呢,因而咱们改进下代码consolenpm
console.log("aaaa"); for(i=1;i<3;i++){ setTimeout(function(){console.log(i)},500);console.log("bbbb"); } for(n=1;n<4;n++){ console.error(n); } console.log("cccc");
运行结果:浏览器
设置了500ms延迟,以后也用了for循环作了3s的阻塞,可是输出结果仍是延时,因此setTimeout执行的延时并不是咱们想象的那样,而结合nodeJs的事件代理,咱们得知当js运行到setTimeout时,实际上为了避免形成阻塞,会将setTimeout时间扔到浏览器的时间队列中,当函数从头至尾执行完后,再抛出咱们setTimeout的输出结果服务器