Node.js
- 运行在服务器端的js
- 用来编写服务器
- 特点:
- 单线程、异步、非阻塞
- 统一API
进程和线程
进程(厂房)
程序的运行的环境
线程(工人)
线程是实际进行运算的东西
同步
- 通常情况代码都是自上向下一行一行执行的
- 前边的代码不执行后边的代码也不会执行
同步带来的问题
- 同步的代码执行会出现阻塞的情况
- 一行代码执行慢会影响到整个程序的执行
常用语言解决同步问题:
- java python
- 通过多线程来解决
- node.js
- 通过异步方式来解决
异步
- 一段代码的执行不会影响到其他的程序
问题:
异步的代码无法通过return来设置返回值
特点:
1.不会阻塞其他代码的执行
2.需要通过回调函数来返回结果
基于回调函数的异步带来的问题
- 代码的可读性差
- 可调试性差
解决办法:
- 需要一个东西,可以代替回调函数来给我们返回结果,就是Promise
Promise
Promise是一个可以用来存储数据的对象
Promise存储数据的方式比较特殊,这种特殊方式使得Promise可以用来存储异步调用的数据
代码执行顺序
调用栈 =>tick队列 => 微任务队列=> 宏任务队列
tick队列
位于微任务与
process.nextTick(callback[, …args])
- 将函数插入到 tick队列中
- tick队列中的代码,会在下一次事件循环之前执行
- 会在微任务队列和宏任务队列中任务之前执行
宏任务和微任务
1.什么是微任务和宏任务
首先,我们要先了解下 Js 。js 是一种单线程语言,简单的说就是:只有一条通道,那么在任务多的情况下,就会出现拥挤的情况,这种情况下就产生了 ‘多线程’ ,但是这种“多线程”是通过单线程模仿的,也就是假的。那么就产生了同步任务和异步任务。
2.JS为什么要区分微任务和宏任务
(1)js是单线程的,但是分同步异步
(2)微任务和宏任务皆为异步任务,它们都属于一个队列
(3)宏任务一般是:script、setTimeout、setInterval、postMessage、MessageChannel、setImmediate(Node.js 环境)
(4)微任务:Promise.then、Object.observe、MutationObserver、process.nextTick(Node.js 环境)
(5)先执行同步再执行异步,异步遇到微任务,先执行微任务,执行完后如果没有微任务,就执行下一个宏任务,如果有微任务,就按顺序一个一个执行微任务
3.微任务和宏任务有哪些
(1)宏任务一般是:script、setTimeout、setInterval、postMessage、MessageChannel、setImmediate(Node.js 环境)
(2)微任务:Promise.then、Object.observe、MutationObserver、process.nextTick(Node.js 环境)
4.微任务和宏任务是怎么执行的?
执行顺序:先执行同步代码,遇到异步宏任务则将异步宏任务放入宏任务队列中,遇到异步微任务则将异步微任务放入微任务队列中,当所有同步代码执行完毕后,再将异步微任务从队列中调入主线程执行,微任务执行完毕后再将异步宏任务从队列中调入主线程执行,一直循环直至所有任务执行完毕。
这里容易产生一个错误的认识:就是微任务先于宏任务执行。实际上是先执行同步任务然后在执行异步任务,异步任务是分宏任务和微任务两种的。
async 和await
通过async可以快速的创建异步函数
异步函数的返回值会自动封装到一个Promise中返回
在async声明的异步函数中可以使用await关键字来调用异步函数
swait
当我们通过await去调用异步函数时,它会暂停代码的运行
直到异步代码执行有结果时,才会将结果返回
注意 await只能用于 async声明的异步函数中,或es模块的顶级作用域中
await阻塞的知识异步函数内部的代码,不会影响外部代码
通过await调用异步代码时,需要通过try-catch来处理异常