关于本书
终于可以完美地花费大量的时间来系统地学习
node.js
了,在之前的很多项目开发工作中,基本上到处都使用node.js
,只不过是简单地使用它的包管理器、还有一些基础的库模块来打包项目的。 但其实 关于node.js它包含的生态大🉐️惊人,简单地从表象上看,它使得我们可以使用同一款编程语言来编写前后端的项目,包括像APP、桌面软件,也都可以使用node.js来提供包管理以及打包服务! 本书所使用的node版本为18.0.0
那么,什么是node.js
?为什么要使用node.js
?如何来使用node.js
?它与传统的后端编程语言相比有什么优劣性?
在学习node.js的相关概念之前,先来了解一下
chrome浏览器
,它是由google出品的,一个世界级标准的浏览器软件,它提供了对js的解释执行程序,这使得我们所编写的js/css都能够在浏览器中被执行! 而node.js则是与chrome类似地,能够使用js来操作所在机器的资源(文件、线程、端口等等),就像java一样,它也包括了一系列的库/包,并 对应的包管理器(npm),使得它可以随意添加、删除包依赖,来实现本地化开发。 chrome与node.js都是集成了google的v8引擎:一个用c++编写的高性能的js与webassembly引擎,该引擎能够独立运行,也可以被嵌入到任何的c++应用中,也就是chrome与node.js。 是关于chrome与node.js是如何具体工作的一个流程:
v8引擎主要负责编译和执行js源代码,处理对象的内存分配,并采用垃圾回收机制来处理不再需要被使用的对象,v8引擎允许任何的c++应用程序向javascript公开自己的对象与函数(也就是说能够与js之间进行一个通讯), 也得益于v8引擎的这个特点,使得我们可以直接编写js去调用c++中的函数以及对象。
开始学习node.js
node.js与java类似,提供了一系列的api,用于操作本地资源(比如网络端口、文件、数据库等等),同时它也提供了一个npm(包管理器), 这意味这我们可以使用node.js来开发web,如下代码所示:
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World!');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
上面我们在3000端口上创建了一个监听,然后当访问的127.0.0.1:3000的时候,就直接返回一个字符串(Hello World!),这个是最基础的一个web服务,一切都将从这里开始!!!
那么,node.js为什么适合做web应用呢?它与传统的比如java、.net、php有什么区别呢?
- node.js基于事件轮训的一个设计原理,而且在一启动的时候,就立刻进行事件的循环中,一旦 对应监听的事件发生的时候,则以回调的方式来响应动作,这里的回调是一个
异步
的动作,与当前的js主线程不在同一个执行线程中; - http是node.js中的一等公民,就是函数对象是js中的一等公民一样,利用该模块,我们可以很方便的来创建一个http服务,而且它在设计的时候,就已经同时考虑到了流式传输和低延迟!
node.js学习辅助
在学习
node.js
的过程中,难免需要针对源码进行一个学习,但是直接硬着头皮来学习关于源码的执行路径以及执行过程的话, 多多少少有点吃力,而且学习效率稍微有点低,虽然阅读源码是必不可少的一个环节,但是 如果 这样子的一种方式来帮助我们更好的阅读源码, 理解node.js的一个执行过程,以及过程中所产生的相关变量的学习的话,那么对于学习源码将会是起到指引性的作用! 来介绍两种调试方式,深入带代码进行调试:
命令行调试 通过执行携带命令参数
--inspect-brk
,使得执行时直接暂时,然后打开chrome浏览器,并输入链接, 找到当前对应的调试中的进程,并点击它 然后在打开的视图窗口中,进行正常的调试,可直接通过单步进入到执行函数中来深入到源码中进行的调试 且在调试的窗口中,可以看到当前程序环境所在的上下文,以及本地变量和全局变量IDE调试(这里以webstorm为例) 在调试的过程中,老是通过命令并切换浏览器调试,感觉不爽,而且我们经常是在自己的开发工具中来进行的开发调试的,因此,我们可以借助于 IDE调试来调试源代码,这里关键在于配置好对应的执行环境之后如下图所示:
源码阅读指导 在接触并深入了解关于
lib
层的代码之后,发现其虽然与我们平时所编写的业务层方面的代码 一定的区别,但是还是可以从一定角度来分析并理解关于node.js
它是如何来设计并编写对应的这个模块的!- 一切从方法入手,也就是当我们想要阅读某个
node.js
模块的时候,从它的module.export
中的关键方法来入手,了解其给我们提供的API; - 从方法引申出关于该模块是如何来创建对应的模块对象的,并将所有的
{}
都收起来,关注模块对象它的Prototype
以及在该原型对象上所调用的实现EventEmitter
等继承动作,因为node.js
大部分模块都是继承于该对象的,使得所有的对象都将拥有对应的on/emit
动作; - 由于创建出来的模块对象一般是需要配合对应的监听动作来工作的,因此大部分是采用
Symbol
变量,来保证其唯一性,并在初始化方法中创建好并存储于对象中,然后在各自的调用方法时,从对象中取出来,并对其进行调用、设置、触发对应的监听器; - 可通过命令行添加
NODE_DEBUG=lib模块名称(以逗号分割)
的方式,来查看关于源码的执行过程中的日志,这样子可以通过这个执行流程了解到关于程序的大体执行顺序,如下结果所示:
- 一切从方法入手,也就是当我们想要阅读某个
node.js源码读后感
在学习
node.js
的源码的时候,我们不单单可以从其源码的角度来理解程序是如何提供对应的api的,还可以学习并模仿关于这个node.js
模块的编写, 以便于我们也能够编写出像node.js
模块类似的业务模块,将业务进行一个解耦。
- 多往
EventEmitter
实现方向靠拢,将目前所需的异步I/O交给底层实现的同时,对应设置对应的异步回调的方式,以callback
的方式来设计并编码自身的模块; - 借助于
Symbol
变量,来创建当前模块独一无二的变量/方法,并将其缓存到Symbol
变量中,方便后续来捞;
如何来学习node.js
制定关于nodejs学习计划:
- 熟悉掌握关于node.js中的每个模块,以及它们对应的一个使用场景与使用方式,将每个模块进行"自定义"归类(根据自己的一个设想,归类出属于自己的所属类目);
- 寻找一个类似于codepen的在线coding网站,能够将自己写的demo直接挂到网页中来运行,并很好的维护对应的code代码;
- 模仿《刻意练习》中的
3F
原则(focus、feedback、fix it),每一个模块都根据其可能运用的一个场景,提供一个自定义的反馈机制(因为我没有导师),将demo上升至小项目小功能的实现,并针对每一次的实现进行思考,以此来改进自己的一个学习过程;- 知识的关联运用,给不同的知识进行关联运用,加深基础知识的一个自我框架整理学习!