JS高级:线程机制与事件机制
进程与线程
进程(process)
程序的一次执行,占有一片独有的内存空间
线程(thread)
是进程内一个独立执行单元
是程序执行的一个完整流程
是CPU最小的调度单元
相关知识
- 应用程序必须运行在某个进程的某个线程上
- 一个进程中至少有一个运行的线程:主线程,进程启动后自动创建
- 一个进程中可以同时运行多个线程
- 一个进程内的数据可以供其中的多个线程直接共享
- 多个进程之间的数据不能直接共享
- 线程池(thread pool):保存多个线程对象的容器,实现线程对象的反复利用
相关问题
- 多线程:
** 优点:有效提升CPU的利用率
** 缺点:创建多线程开销;线程间切换开销;死锁与状态同步问题 - JS单线程
- 浏览器运行 多线程,多进程(chrome,IE),单进程(firefox)
浏览器内核
支撑浏览器运行的最核心程序
组成
- JS引擎模块:负责js的编译与运行
- html,css文档解析模块:负责页面文本的解析
- DOM/CSS模块:负责dom/css在内存中的相关处理
- 布局和渲染模块:负责页面的布局和效果的绘制
- 定时器模块:负责定时器的管理
- 事件响应模块:负责事件的管理
- 网络请求模块:负责ajax请求
- …
定时器
定时器定时执行吗?
- 定时器不能保证真正定时执行
- 一般会延迟一点,也可能也能吃很长时间
定时器回调函数在主线程执行
JS是单线程的
如何证明
- setTimeout()的回调函数是在主线程执行的
- 定时器回调函数只有在运行栈中的代码全部执行完后才有可能执行
JS用单线程的原因
- 主要用途是与用户互动,操作DOM
- 只能是单线程,否则会带来复杂的同步问题
js引擎执行代码的基本流程
- 先执行初始化代码:
** 设置定时器
** 绑定监听
** 发送ajax请求 - 在某个时刻执行回调代码
事件循环模型
初始代码分类
- 初始化执行代码(同步代码):包含绑定dom事件监听,设置定时器,发送ajax请求的代码
- 回调执行代码(异步代码):处理回调逻辑
Web Workers
相关API
- Worker:构造函数,加载分线程执行的js文件
var worker = new Worker("worker.js")
- Worker.prototype.onmessage:用于接受另一个线程的回调函数
worker.onmessage = function(event) { console.log(event.data)}
- Worker.prototype.postMessage:向另一个线程发送消息
worker.postMessage(data1)
不足
- worker内代码不能操作DOM
- 不能跨域加载JS
- 不是每个浏览器都支持这个新特性
使用
- 创建在分线程执行的js文件
var worker = new Worker("worker.js")
worker.onmessage = function(event) {event.data}
woker.postMessage(data1)
- 在主线程中的js中发消息并设置回调