理解 JavaScript 的单线程
简单来说JavaScript 语言规范规定了它的执行模型是单线程的但承载它的运行环境浏览器或 Node.js是多进程的。一、为什么说 JS 是“单线程”这里的“单线程”指的是 JavaScript 的“执行上下文”和“内存模型”。主线程的唯一性在浏览器中JS 引擎如 V8在渲染进程中运行。为了保证网页的稳定性JS 引擎在同一时刻只能做一件事。核心原因DOM 操作。如果 JS 是多线程的线程 A 修改了 DOM 节点线程 B 同时删除了这个节点浏览器该听谁的为了避免这种复杂的“竞态条件”和数据不一致JS 从诞生之初就被设计为单线程直接操作唯一的 DOM 树。调用栈Call StackJS 代码执行时函数是依次压入一个“栈”中的。这个栈一次只能弹出一个函数执行必须等当前函数执行完才能执行下一个。这就是典型的单线程行为。二、为什么说 JS 不是“单进程”这里的“进程”指的是 操作系统层面的资源分配单位。浏览器的多进程架构现代浏览器如 Chrome是一个典型的多进程应用程序。当你打开一个标签页时浏览器通常会为它创建一个新的渲染进程Renderer Process。好处如果一个网页崩溃了比如内存溢出它只会影响当前这个标签页的进程而不会导致整个浏览器崩溃也不会影响你打开的其他网页。隔离每个进程都有自己独立的内存空间和资源互不干扰。三、关系举例我们可以把浏览器想象成一个“大工厂”层级概念比喻说明操作系统层进程 (Process)工厂车间浏览器为每个标签页开一个独立的车间。车间之间互不干扰资源隔离。进程内部线程 (Thread)流水线/工人车间里有多个工人渲染工人画页面、网络工人下载资源、JS 工人写逻辑。JS 层面JS 主线程JS 工人关键点虽然车间里有很多工人但负责执行 JS 代码的“JS 工人”只有一个。他必须按顺序处理代码不能分身。四、误区误区1“浏览器有网络线程、定时器线程所以 JS 是多线程的”事实是这些线程属于浏览器内核不属于 JS 引擎。JS 引擎只负责执行代码。当 setTimeout 触发时是浏览器的定时器线程在倒计时时间到了之后它把回调函数扔进 JS 的“任务队列”里等待 JS 主线程空闲时再去执行。JS 主线程依然是单线程工作的。误区2“Web Worker 不是多线程吗”事实是Web Worker 确实是开辟了一个新的线程但它是一个受限的线程。它不能操作 DOM也不能修改全局变量。它更像是一个“外包团队”主线程把数据发给它它算完把结果发回来。这并没有改变 JS 主线程单线程操作 DOM 的本质。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2517924.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!