what is nodejs
nodejs 是在计算机上运行 js 的一个平台,在 nodejs 之前,js 只能在浏览器环境中运行
比如我们可以在浏览器中 alert 一个信息,但是在电脑终端上无法识别
这就是 nodejs 在做的,可以让 js 代码被计算机识别,可以让 js 访问计算机操作系统,可以去读写文件,去连接数据库等等
为什么要学习 nodejs 呢?
- nodejs 是 js 语法,对于前端开发同学很友好,可以用同一种语言写前后端
- nodejs 非常的快,因为他在 google v8 引擎的基础上运行(v8 引擎是 google 开源的一个高性能的引擎,用 c++ 写的,chrome 同样也用的 v8 引擎,v8 引擎把 js 代码编译成更快的机器语言,机器语言是低级别语言,可以被计算机直接执行)
- nodejs 使用 npm 包管理工具,是全球最大的开源工具
- nodejs 可以很好的构建实时应用
- nodejs 可以构建 网页、移动端 和 桌面应用
javascript environment browser/server
浏览器中,window 是顶级对象,代表脚本正在运行的窗口,其中的 document 属性指向的是窗口中载入的 DOM 文档
nodejs 中,类比与浏览器的 window 对象,nodejs 中是 global 对象,global 对象里的 process 类似于浏览器中的 document
event loop
js 本身是单线程的,只有一个调用堆栈,按理说如果是单线程,一个耗时较长的任务,比如读取文件,就会占用住这个线程,让后面的任务无法执行。但是因为 nodejs 存在事件循环队列(先进先出),在 js 单线程中任务执行完成后,会把事件循环队列中的所有事件,加入到单线程的调用堆栈中执行。
但是事件循环队列这里分为 promise queue(微任务) 和 callback queue(宏任务),微任务不会等当前循环队列清空,会在当前直接队列后直接执行,宏任务会在当前事件队列清空后执行。
微任务:process.nextTick、Promise、async/await
宏任务:setTimeout、setImmediate(在同一个 I/O 周期内,setImmediate 肯定在 setTimeout 之前执行。虽然叫 setImmediate,但是它的执行时机,实际上是在 process.nextTick 之后的)
因为 nodejs 可以通过回调函数处理异步的任务,所以是一个单线程的非阻塞的 I/O 模型
asynchronours(non-blocking)vs synchronous(blocking)
因为 nodejs 可以通过回调函数处理异步的任务,所以是一个单线程的非阻塞的 I/O 模型
一些其他语言,像 PHP、Ruby 是多线程的阻塞 I/O,比如连接数据库时,可能会花费几百毫秒甚至一秒等待数据库返回,他们在等待数据库返回的时间内,不能做其他事情,于是需要开启新线程去做其他的事情
nodejs 中,比如去异步读取文件
fs.readFile(fileName, (err, data) => {
if(err){
console.log(err);
}
console.log(data.toString());
})
console.log('started')
// started
// 123(data.toString() output)
但是 nodejs 也可以提供同步读取文件的方法,会占用单线程,在完全前不能做其他事情,但是一般都不会使用
const data = fs.readFileSync(fileName);
console.log(data.toString());
console.log('started')
// 123(data.toString() output)
// started