试想一下,如果一个网页打开之后加载数据5秒才加载完,然后渲染出来,这个用户估计以为这个网站挂掉了吧?然后大部分用户会选择离开。如何解决这个问题?我们可以采用一部分一部分加载的形式去加载,同时去请求,响应的请求就可以先实现响应的部分,这样的用户体验就更好一些。Node.js正好有相关的机制,可以去做到这个效果,叫做异步I/O。
假设业务场景中有一组互不相关的任务需要完成,现在主流的两种方法是:(1)单线程串行依次执行(2)多线程并行完成。如果创建多线程的开销小于并行执行的开销,那么毫无疑问是选择创建多线程,但是多线程会存在锁的问题。至于单线程串行执行,这个对于程序员来说,当然是最友好的,但是通常在很多业务逻辑里面,需要进行多次略慢的任务,一个任务的执行受到上一个任务的影响,所以整体来说也不是特别高校。
Node.js在这两种方法当中做了一个平衡,利用单线程,远离多线程死锁、状态同步等问题,利用异步I/O,让单线程避免来阻塞的问题,更好的利用CPU资源。
在进程启动时,Node会创建一个类似while(true)的循环,每次循环为一个Tick,每次Tick都会看是否有还没完成的事件处理,如果有就进行处理,如果没有就跳出进程,流程图如下:
在每个Tick 的过程中,如何判断是否有事件需要处理呢?Node.js引入了观察者的角色,比如文件I/O观察者、网络I/O观察者等等,这些事件被传递到对应的观察者那里,事件循环从观察者那里取出事件并处理。
可以看出,事件循环是异步实现的核心,它与浏览器中的执行模型基本保持了一致,Node正是依靠构建了一套完善的高性能异步I/O框架,打破了Javascript在服务器端止步不前的局面。
网友评论