既然说要好好学Node,那么对应的Node的发展历程是学习Node过程中必不可少的一步,文中作者对Node诞生的历程进行了简单的讲解:
从瑞恩达尔博客中宣布准备基于V8创建一个轻量级的WEB服务器并且提供一套库
之后就慢慢从Github发布了第一个版本,之后又有了云计算公司的资助,瑞恩达尔全职开发Node,再到之后的window版本的Node支持,再到之后的掌门人的身份转交给了NPM的设计者
01|为什么是JavaScript?
之所以是JavaScript就不得不讲讲当时瑞恩达尔通过博客宣布自己要做轻量级的WEB服务器的初衷了!
当然它的背景主要是C/C++是一名围绕着性能Web服务器的资深程序员! 他后面找到了关于高性能比较关键的几个要素:
- 事件驱动
- 非阻塞IO
在对不同的语言进行了一番评估之后,最终敲定了使用JavaScript作为Node实现语言如下所示:
- 没有历史包袱
- 开发门槛低
- 广泛的事件驱动的应用
- Chrome浏览器的JavaScript引擎V8的高性能
- 为什么叫做Node
起初瑞恩达尔最初的名字叫做web.js,就是所谓的Web服务器,但是之后的发展超出了他最初只开发Web服务器的想法,变成了构建网络应用的基础框架,那么便可以在他的基础之上构建出更多的应用:
- 服务器
- 客户端
- 命令行工具,等等
Node发展成了不共享任何资源的单进程单线程的适宜网络的库,对应的目标也是构建快速的可伸缩的网络应用平台!
非常容易通过拓展来达成构建大型网络应用,每一个node进程都是构成网络应用中的一个节点,因此Node本身也就有一定的意味!
02|Node VS Chrome?
我们简单针对Node和Chrome的构成进行比较
- Chrome
- HTML
- JavaScript
- WebKit
- V8
中间层
- 网卡,硬盘,显卡....
- Node
- JavaScript
- V8
中间层(libuv)
- 网卡,硬盘
node的出现,打破了JavaScript只能够运行在浏览器端的局面,给JavaScript带来了更多的可能!
03|Node的特点
- 异步IO
异步IO其实对于前端工程师来讲的话还是比较容易的,我们以一个简单的Ajax请求进行阐述:
$.post("/url",{title:"ProbeDream"},data=>{
    console.log("收到响应!");//2.后执行
});
console.log("发送Ajax请求结束!");//1.先执行
改代码中,收到响应!的时间是不确定的,取决于异步操作的结束,并且没有具体的结束时间! 是一种关注结果但并不关注过程的一种表现
但是如果说实在node中的话是这样的:
const fs = require("fs");
fs.readFile("/path",(error,data)=>{
    console.log("读取文件完成");//2.后执行
});
console.log("发送读取文件");//1.先执行
在Node中绝大多数的操作都是通过异步的方式进行调用,瑞恩达尔排除万难在底层构建了很多异步IO的API,从文件读取到网络请求,极大程度上的方便了我们开发者自然地进行IO操作,每个调用之间无需等待前一个的操作结束,在对应的编程模型上大大提升了效率!
通过对应的代码实例可以看出来:
const fs = require("fs");
fs.readFile("/path1",(error,data)=>{
    console.log("读取文件1完成!");
});
fs.readFile("/path2",(error,data)=>{
    console.log("读取文件完成");
})
对应的两个文件的读取操作的时间,取决于耗时最慢那个文件的读取操作
如果说是同步的操作呢? 那么耗时是两个任务的耗时之和!
- 事件与回调函数
我们通过对应的例子展示Ajax异步提交服务器端处理过程:
const http = require("http");
const queryString = require("querystring");
const server = http.createServer((request,response)=>{
    let postData = "";
    request.setEncoding("utf-8");
    /* data event handle */
    request.on('data',chunk=>{
        postData += chunk;
    });
    request.on("end",()=>{
        response.end(postData);
    });
});
server.listen(8080,()=>{
    console.log(`This Server Running at the http://localhost:8080`);
})
console.log(`The Server status is Done!`);
Ajax请求的发送:
$.ajax({
    "url":"url",
    "method":"POST",
    "data":{},
    "success":data=>{
        //TODO
    }
})
事件的编程方式具有轻量级,松耦合,只关注事务点的优势,但是如果说涉及到多个异步任务的情况下,事件与事件之间的独立性,如果协作?
同时Node与其他的Web后端语言相比,除了所谓的异步和事件之外,回调函数其实不得不提,回调函数也最好是接收异步调用返回数据的方式! 当然习惯了同步方式变成的人如果说要面对这种情况的话还是有点不习惯的!
关于之后的流程控制与时间写作方法与技巧在之后会讲到!
- 单线程
对应的node保持了JavaScript在浏览器中单线程的特点,node中无法与其他线程共享状态!
单线程的好处体现在哪里?
- 不用像多线程那样在意状态的同步问题! 没有所谓的死锁的存在,也就没有所谓的线程上下文交换的开销成本!
可能有些人会问到,不能够只单纯提到了单线程的优点,弱点避而不谈,弱点如下所示:
- 无法利用多核CPU
- 错误会引起整个应用的退出,比较考验应用的健壮性
- 大量的计算导致CPU无法继续调用异步IO (长时间的CPU占用会导致异步IO发不出,完成的异步IO的回调函数也得不到及时执行!)
- 跨平台
一开始只能够运行在Linux上面,但是后面微软团队注意到了它,微软团队帮助Node实现Window的兼容! 现在的Node已经可以直接在Window上面运行了!
对应的架构图也如下所示:
- Node.js
- libuv
- 平台兼容层
- *nix
- Windows
 
其中的libuv已经成为了许多系统实现跨平台的基础组件! 在Node中作为平台层架构的角色出现在Node的架构之中!
对应的Node应用场景在哪些方面?
- IO密集型(Node面向网络且擅长并行IO,能够有效地组织起更多的硬件资源,从而提供更多好的服务) 
- 
是否不擅长CPU密集型任务 - Node是足够高效的,优秀的运算能力来自于V8
- 对应的还可以通过编写C/C++拓展高效地利用CPU
- 合理地调度资源才是处理CPU密集型任务的最佳姿势!
 
- 分布式应用 
本文只是对深入浅出Node.js一章节进行简单的阐述,因为自己也没有Node的使用经验,如果你感兴趣的话,欢迎在评论区与我交流!