创始者认为 web 服务器有两个要点,事件驱动和非阻塞 I/O。前端
最初创始者想将其命名为 web.js 也就是一个 web 服务器,可是项目的发展超过了他最初单纯开发一个 web 服务器的想法,变成了构建网络应用的基础框架。node
V8 给 Chrome 浏览器带来了强劲的心脏,也成为了 JavaScript 称为 node 语言的很大权重值。web
Chrome 浏览器和 Node 组件构成 区别以下图: 浏览器中,除了 v8 引擎还有一个 webkit 布局引擎,HTML5 使得浏览器开放了不少功能给前端的 HTML 及 JavaScript,可是HTML5 的统一却相对缓慢,JavaScript 做为一个图灵完备的语言,受限于浏览器中间层提供的支持。 除了 HTML 、webkit 和 显卡这些UI 相关的技术没有支持外,Node 结构与 Chrome 十分相近。 它们都是基于事件驱动的一步架构,浏览器经过事件驱动来服务界面上的交互,Node 经过事件驱动来服务 I/O。 Node 中,JavaScript 能够为所欲为的访问本地文件,搭建 websocket 服务端,能够链接数据库,可使用多进程。 JavaScript 再也不限制于浏览器与 CSS 样式表、DOM 树。 Node 不处理 UI,但用浏览器相同的机制和原理运行。 打破了 JavaScript 只能在浏览器中运行的局面,下降了先后端转换所须要的上下文交换代价。数据库
前端经常使用到的就是经过 AJAX 请求数据,发送和收到之间有一个时间的间隔,在收到数据后后续代码当即执行,可是收到的时间确是不肯定的,这是一种只注重结果,不注重过程的表现。以下图所示。 在 Node 中异步 I/O 也很常见,能够用读取文件为例:编程
const fs = require('fs');
fs.readFile('../Desktop/IMG_3648.jpeg', (err, file) => {
console.log(file);
console.log('文件读取完成');
});
console.log('发起读文件的流程!');
复制代码
代码中示例“发起读取文件的流程”先于“文件读取完成”执行,什么时候完成基于核实彻底读取内容,执行流程以下图: 在 Node 中,咱们能够从语言层面很天然的进行并行的 I/O 操做,每一个调用之间无需等待以前的 I/O 调用完成,读取两个 文件的最慢速度取决于读取最慢的那个文件的耗时。对于同步 I/O 则是两个文件的综合。windows
事件的编程方式具备轻量级、松耦合、只关注实物点等优点,可是在多个异步任务的场景下,事件与事件之间各自独立,如何协做是一个问题。 函数做为JavaScript 的第一等公民,将函数做为对象传递给方法做为实参进行调用。回调函数是最好的接受异步调用返回数据的方式。后端
Node 保持了JavaScript 单线程的特色,单线程最大的好处就是无需像多线程同样到处在乎状态同步的问题,没有死锁存在,也没有线程上下文交换带来的性能开销。 单线程的弱点:浏览器
为解决这些问题,Google 开发了 Gears, HTML5 标准增长了 web workers 标准,Google 放弃了 Gears 支持 web workers。 Web workers 可建立线程进行计算,已解决 JavaScript 大计算阻塞 UI 渲染的问题。 Node 采用了与 web workers 相同的思路解决单线程中大量计算的问题: child_process。服务器
最初的 node 只可在 Linux 上使用,后续增长了 windows 平台的支持。websocket
I/O 密集型的优点主要在于 Node 利用时间循环的处理能力,而不是启动每个线程为每个请求服务,资源占用极少,因此 Node 面向网络并擅长并行 I/O。
CPU 密集型业务在Node 上的支持并不可怕,可是会带来的挑战是:JavaScript 做为单线程的语言,CPU 密集型业务会占用长时间的线程进行计算,致使 CPU 时间片没法释放,使得后续的 I/O 没法发起,可是适当调整和分解大型运算任务为多个小任务,使得运算能够及时释放,不阻塞 I/O 调用的发起,这样既能够享受到异步 I/O 的好处,也能充分利用 CPU。
若是是纯 CPU 的业务,能够经过两种方式进行充分利用 CPU
Node 能够经过将旧有的接口做为数据源,发挥并行优点,不关心背后用什么语言实现。
Node 高效利用 I/O 的过程也是高效使用数据库的过程,对于 Node 而言,使用数据库这种行为只是一次普通的 I/O。对数据库而言倒是一次复杂的计算,也是充分压榨硬件资源的过程。