关于本书

终于可以完美地花费大量的时间来系统地学习node.js了,在之前的很多项目开发工作中,基本上到处都使用node.js,只不过是简单地使用它的包管理器、还有一些基础的库模块来打包项目的。 但其实 :warning: 关于node.js它包含的生态大🉐️惊人,简单地从表象上看,它使得我们可以使用同一款编程语言来编写前后端的项目,包括像APP、桌面软件,也都可以使用node.js来提供包管理以及打包服务! 本书所使用的node版本为18.0.0

:trollface: 那么,什么是node.js?为什么要使用node.js?如何来使用node.js?它与传统的后端编程语言相比有什么优劣性?

在学习node.js的相关概念之前,先来了解一下chrome浏览器,它是由google出品的,一个世界级标准的浏览器软件,它提供了对js的解释执行程序,这使得我们所编写的js/css都能够在浏览器中被执行! 而node.js则是与chrome类似地,能够使用js来操作所在机器的资源(文件、线程、端口等等),就像java一样,它也包括了一系列的库/包,并 :u6307: 对应的包管理器(npm),使得它可以随意添加、删除包依赖,来实现本地化开发。 chrome与node.js都是集成了google的v8引擎:一个用c++编写的高性能的js与webassembly引擎,该引擎能够独立运行,也可以被嵌入到任何的c++应用中,也就是chrome与node.js。 :point_down: 是关于chrome与node.js是如何具体工作的一个流程:

nodejs与chrome的一个js执行过程

:stars: v8引擎主要负责编译和执行js源代码,处理对象的内存分配,并采用垃圾回收机制来处理不再需要被使用的对象,v8引擎允许任何的c++应用程序向javascript公开自己的对象与函数(也就是说能够与js之间进行一个通讯), 也得益于v8引擎的这个特点,使得我们可以直接编写js去调用c++中的函数以及对象。

开始学习node.js

node.js与java类似,提供了一系列的api,用于操作本地资源(比如网络端口、文件、数据库等等),同时它也提供了一个npm(包管理器), :point_right: 这意味这我们可以使用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}/`);
  });

第一个nodejs例子

:point_up_2: 上面我们在3000端口上创建了一个监听,然后当访问的127.0.0.1:3000的时候,就直接返回一个字符串(Hello World!),这个是最基础的一个web服务,一切都将从这里开始!!!

:trollface: 那么,node.js为什么适合做web应用呢?它与传统的比如java、.net、php有什么区别呢?

  1. node.js基于事件轮训的一个设计原理,而且在一启动的时候,就立刻进行事件的循环中,一旦 :u6307: 对应监听的事件发生的时候,则以回调的方式来响应动作,这里的回调是一个异步的动作,与当前的js主线程不在同一个执行线程中;
  2. http是node.js中的一等公民,就是函数对象是js中的一等公民一样,利用该模块,我们可以很方便的来创建一个http服务,而且它在设计的时候,就已经同时考虑到了流式传输和低延迟!

node.js学习辅助

在学习node.js的过程中,难免需要针对源码进行一个学习,但是直接硬着头皮来学习关于源码的执行路径以及执行过程的话, 多多少少有点吃力,而且学习效率稍微有点低,虽然阅读源码是必不可少的一个环节,但是 :confused: 如果 :u6709: :point_down: 这样子的一种方式来帮助我们更好的阅读源码, 理解node.js的一个执行过程,以及过程中所产生的相关变量的学习的话,那么对于学习源码将会是起到指引性的作用! :point_down: 来介绍两种调试方式,深入带代码进行调试:

  1. 命令行调试 通过执行携带命令参数--inspect-brk,使得执行时直接暂时,然后打开chrome浏览器,并输入链接, 找到当前对应的调试中的进程,并点击它 找到当前正处于断点的进程 然后在打开的视图窗口中,进行正常的调试,可直接通过单步进入到执行函数中来深入到源码中进行的调试 浏览器调试 且在调试的窗口中,可以看到当前程序环境所在的上下文,以及本地变量和全局变量

  2. IDE调试(这里以webstorm为例) 在调试的过程中,老是通过命令并切换浏览器调试,感觉不爽,而且我们经常是在自己的开发工具中来进行的开发调试的,因此,我们可以借助于 IDE调试来调试源代码,这里关键在于配置好对应的执行环境之后如下图所示: webstorm源码调试

  3. 源码阅读指导 在接触并深入了解关于lib层的代码之后,发现其虽然与我们平时所编写的业务层方面的代码 :u6709: 一定的区别,但是还是可以从一定角度来分析并理解关于node.js 它是如何来设计并编写对应的这个模块的!

    • 一切从方法入手,也就是当我们想要阅读某个node.js模块的时候,从它的module.export中的关键方法来入手,了解其给我们提供的API;
    • 从方法引申出关于该模块是如何来创建对应的模块对象的,并将所有的{}都收起来,关注模块对象它的Prototype以及在该原型对象上所调用的实现EventEmitter等继承动作,因为node.js大部分模块都是继承于该对象的,使得所有的对象都将拥有对应的on/emit动作;
    • 由于创建出来的模块对象一般是需要配合对应的监听动作来工作的,因此大部分是采用Symbol变量,来保证其唯一性,并在初始化方法中创建好并存储于对象中,然后在各自的调用方法时,从对象中取出来,并对其进行调用、设置、触发对应的监听器;
    • 可通过命令行添加NODE_DEBUG=lib模块名称(以逗号分割)的方式,来查看关于源码的执行过程中的日志,这样子可以通过这个执行流程了解到关于程序的大体执行顺序,如下结果所示:输出日志来大体了解程序执行流程.png

node.js源码读后感

在学习node.js的源码的时候,我们不单单可以从其源码的角度来理解程序是如何提供对应的api的,还可以学习并模仿关于这个node.js模块的编写, 以便于我们也能够编写出像node.js模块类似的业务模块,将业务进行一个解耦。

  1. 多往EventEmitter实现方向靠拢,将目前所需的异步I/O交给底层实现的同时,对应设置对应的异步回调的方式,以callback的方式来设计并编码自身的模块;
  2. 借助于Symbol变量,来创建当前模块独一无二的变量/方法,并将其缓存到Symbol变量中,方便后续来捞;

如何来学习node.js

制定关于nodejs学习计划:

  1. 熟悉掌握关于node.js中的每个模块,以及它们对应的一个使用场景与使用方式,将每个模块进行"自定义"归类(根据自己的一个设想,归类出属于自己的所属类目);
  2. 寻找一个类似于codepen的在线coding网站,能够将自己写的demo直接挂到网页中来运行,并很好的维护对应的code代码;
  3. 模仿《刻意练习》中的3F原则(focus、feedback、fix it),每一个模块都根据其可能运用的一个场景,提供一个自定义的反馈机制(因为我没有导师),将demo上升至小项目小功能的实现,并针对每一次的实现进行思考,以此来改进自己的一个学习过程;
  4. 知识的关联运用,给不同的知识进行关联运用,加深基础知识的一个自我框架整理学习!

Node.js生态

results matching ""

    No results matching ""