进程
-
进程是系统分配资源的最小单位
-
每个进程是独立的,但是可以通过进程通信,做到进程间的通信
-
浏览是一个多进程模块,对于浏览器而言,每个页签都是一个进程
- 好处就是安全,网页独立,隔离不能互相访问
-
浏览器的主要进程,主要负责管理我们的页面
-
网络进程,发请求 ajax资源的加载
-
插件进程
-
GPU进程 处理图形 加快图形处理速度
-
渲染进程(每个页面都有一个自己的渲染进程)
-
-
js主线程是单线程的(js引擎线程+渲染进程 互斥)webworker不能操作dom元素
-
网络线程
-
事件触发线程(调度异步任务)
- EventLoop(定时器、事件 都会产生对应的线程)
-
EventLoop
-
任务也是具备优先级的
-
宏任务:(浏览器提供)脚本执行、UI渲染、定时器、请求、MessageChannel、setImmediate(IE独有)
-
微任务:(语言提供的就是微任务)promise.then、mutationObserver、queueMicroTask
-
默认会拿出一个宏任务执行,宏任务执行的时候会产生n个微任务,当宏任务执行完毕后会清空微任务。每次执行一个宏任务,执行多个微任务
-
-
浏览器默认有多个宏任务队列,但是我们只关心eventLoop中调用的逻辑,所以我们通常说有一个宏任务队列。
-
requestFrameAnmation、requestIDleback是ui渲染相关的,我们称之为钩子
案例
<script>
document.body.style.background = 'red';
console.log(1)
Promise.resolve().then(()=>{
console.log(2)
document.body.style.background = 'yellow'; // then方法的执行一定是在浏览器渲染之前发生的
})
console.log(3);
</script>
// 用户点击按钮,会产生两个回调会放到宏任务队列中,按照宏任务的调度方式每次拿出一个来执行
button.addEventListener('click',()=>{
console.log('listener1');
Promise.resolve().then(()=>console.log('micro task1'))
})
button.addEventListener('click',()=>{
console.log('listener2');
Promise.resolve().then(()=>console.log('micro task2'))
})
button.click(); // 自动点击,则在当前的宏任务中直接执行了从上往下 listener1 -> listener2 -> micro task1 ->micro task2
node特点
- 异步非阻塞i/o
- 事件驱动(支持js语法,不支持bom和dom,有很多内置模块)
- 所谓事件驱动是按照事件的顺序来触发处理逻辑 (事件环) 读写操作完成后会放到对应的队列中, 等待事件环来触发对应的事件
多线程
- 可以同时执行多个任务,每个任务分配一个线程
- 优点是可以并行
- 缺点是浪费资源
- 适合cpu密集型操作(压缩、加密)
单线程
- 只有一个,节约内存,不适合cpu密集型操作
- 适合i/o密集型
- 缺点是容易阻塞
Node适合做什么?
- 编写前端工具 工具链 vite rollup webpack gulp,脚手架 (好处是js)
- 为前端服务的后端, 中间层 ((client) (bff,格式化,云服务,处理跨域,代理)) (server)
- 创建服务器 koa express eggjs nestjs 可以用来开发服务器
- 聊天,socket.io 即时通讯、爬虫、ssr 都可以在node中去搞
模块化规范解决了哪些问题?
- 命名冲突,代码隔离上的问题,方便代码的复用,提升代码的可扩展性
- 按照每个文件来划分模块,一个文件就是一个独立的模块 (在每个文件的外面都包装了一个函数)
commonjs规范
规范的目的就是定义 如何导出一个模块, 如果让别人引用我. 做到多个文件之间共享逻辑的处理
- 每个js文件都是一个模块
- 如果你想给别人用自己的逻辑 module.exports 导出
- 别人想使用我,采用require语法来使用我。 require()
require加载过程
1.调用的是require方法
2.加载模块 Module._load
3.通过Module._resolveFilename 核心就是给我们的路径添加后缀 (会帮我们转成绝对路径)
4.如果这个文件被加载过,走缓存,否则再去加载模块
5.加载模块的核心就是创建一个模块的实例 new Module() -> {id:文件,exports:模块导出结果是什么}
6.将模块缓存起来
7.要加载文件要看加载的文件的扩展名是什么.js / .json
8.根据扩展名找到对应的加载方案 (策略) 加载js的策略
9.js的加载就是读取文件内容
10.就是给内容包装一个函数,让这个函数执行 (代码里面肯定会给module.exports 赋值)
process.nextTick
- 优先级高于微任务