【8.7】nodejs 学习 - nodejs 基本概念和特点

377 阅读3分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

nodejs 的基本概念

nodejs 是 2009 年由 Dyan Dahl 发布,nodejs 是在计算机运行 js 的平台,在它之前,js 只能在浏览器中运行。

可以测试一下,我们在浏览器控制台中 alert 信息,是可以的,但是在电脑终端中不能识别

image.png

nodejs 的组成部分

chrome 浏览器

  • HTML
    • webkit
  • JavaScript
    • V8
  • 中间层
  • 网卡、硬盘、显卡... Node
  • JavaScript
    • V8
  • 中间层(libuv)
  • 网卡、硬盘...

由此可见,除了没有 webkit、显卡这类和 UI 展示相关的技术之外,Node 的结构和浏览器的十分相似。

nodejs 的特点

异步 I/O

由于 js 单线程的特点,如果读取文件等操作是同步操作的话,随着文件的增大,这种耗时较大的任务,长时间占用单线程,会导致后面的任务不能执行。

于是 nodejs 的作者排除万难,在底层构建了很多异步 I/O 的 API,从文件读取到网络请求等。这样做的话,nodejs 很自然的处理并行的 I/O 操作,每个操作不需要等待上一个操作结束。比如异步读取文件。


const fs = require('fs');
const fileName = 'target.txt';

const errHander = (err) => {
  console.log(err);
}

const dataHander = (data) => {
  console.log(data.toString())
}

fs.readFile(fileName, (err, data) => {
  if(err){
    errHander(err);
  }
  dataHander(data);
})

相对于其他语言比如 PHP、Ruby 是多线程的阻塞IO,多线程的意思是每次有一个新的任务,需要多开一个线程。比如连接数据库,从数据库里查数据,可能会等待几秒钟,在这段时间内,像 PHP、Ruby 当前线程都是被阻塞住的,于是需要单独开一个线程。

nodejs 不会阻塞,因为有回调函数,在下面说到

事件和回调函数

事件的特点是轻量级、松耦合、只关注事物点。

回调函数对于前端同学来说非常熟悉了,还是以上面的例子为例,代码的编写顺序和执行顺序没有关系,在回调函数执行完成后,将结果放到回调队列中,在单线程执行完成后,放入线程执行

单线程

js 的单线程前面提过很多次,单线程的好处是不需要像多线程那样处处在意线程间的状态同步问题,没有死锁,也没有线程上下文交换带来的性能上的开销

单线程也有自身的弱点:无法利用多核 CPU;错误会引起整个应用程序退出;大量计算的任务,占用 CPU,也会导致无法继续调用异步 I/O。

为了解决这些问题,nodejs 提供 API,可以创建子进程(child_process),解决调健壮性和无法利用多核 CPU 的问题,另外也可以将大量计算分散到各个子进程,通过进程间的消息通信来传递结果。

跨平台

nodejs 可以基于 libuv 带来的兼容,同时在 windows 和 *nix 上运行,libuv 是很多系统实现跨平台的基础组件。 nodejs 的第三方 C++ 扩展模块,也可以通过 libuv 实现跨平台。