浏览器的内核是多线程的,一个浏览器一般至少实现三个常驻线程:JavaScript引擎线程,GUI渲染线程,浏览器事件触发线程。
a.JavaScript引擎是基于事件驱动单线程执行的,js引擎一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个js线程在运行JS程序。
b.GUI渲染线程负责渲染浏览器界面,当界面需要重排、重绘或由于某种操作引发回流时,该线程就会执行。但需要注意 GUI渲染线程与JS引擎是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。
c.事件触发线程,当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeOut、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。
当我们要循环过百万级的数据甚至亿的时候怎么办?那就用setTimeout模拟一个多线程。
重点:js的工作机制是:当线程中没有执行任何同步代码的前提下才会执行异步代码,setTimeout是异步代码,所以setTimeout只能等js空闲才会执行,但死循环是永远不会空闲的,所以setTimeout也永远不会执行。即使setTimeout为0,他也是等js引擎的代码执行完之后才会插入到js引擎线程的最后执行。
例子:
var thread = function () {
var nowTime = 0, //线程已经执行了多久
maxTime = 15;//线程最多执行多久
var threadArr = [];//数组模拟线程队列
this.addThread = function (fn) {
threadArr.push(fn)
}
this.start=function () {
doingThread();
}
var doingThread = function () {
if (threadArr.length > 0) {
if (nowTime < maxTime) {
let now = new Date().getTime();
var method = threadArr[0];
method();
threadArr.splice(0, 1);
let nowNew = (new Date().getTime() - now);
nowTime += nowNew;
doingThread();
} else {//每执行完线程后睡1ms
nowTime=0;
setTimeout(doingThread, 1);
}
}else {//先睡着等待线程队列
setTimeout(doingThread,100)
}
}
}
var fn = function (num) {
console.log(num)
}
var thread = new thread();
thread.start()
for (let i = 0; i < 1000000; i++) {
thread.addThread(function () {
fn(i)
})
}
循环百万级的数据量并且不阻塞Ui线程是完全没问题的,但过亿浏览器还是会蹦。(这里只是提供个简单的思路,其实过亿也可以不蹦)
原文来源:https://segmentfault.com/a/1190000008723632
进程与线程是操作系统中两个重要的角色,它们维系着不同程序的执行流程,通过系统内核的调度,完成多任务执行。今天我们从 Node.js(以下简称 Node)的角度来一起学习相关知识,通过本文读者将了解 Node 进程与线程的特点、代码层面的使用以及它们之间的通信。
注意这个题目问的是进程切换与线程切换的区别,不是进程与线程的区别。当然这里的线程指的是同一个进程中的线程。这个问题能很好的考察面试者对进程和线程的理解深度,有比较高的区分度。
多年以来,Node.js 都不是实现高 CPU 密集型应用的最佳选择,这主要就是因为 JavaScript 的单线程。作为对此问题的解决方案,Node.js v10.5.0 通过 worker_threads 模块引入了实验性的 “worker 线程” 概念
几乎在每一本JS相关的书籍中,都会说JS是单线程的,JS是通过事件队列(Event Loop)的方式来实现异步回调的。 对很多初学JS的人来说,根本搞不清楚单线程的JS为什么拥有异步的能力,所以,我试图从进程、线程的角度来解释这个问题
JS本质是单线程的。也就是说,它并不能像JAVA语言那样,两个线程并发执行。 但我们平时看到的JS,分明是可以同时运作很多任务的,这又是怎么回事呢?
当我们执行 JS 代码的时候其实就是往执行栈中放入函数,那么遇到异步代码的时候该怎么办?其实当遇到异步的代码时,会被挂起并在需要执行的时候加入到 Task(有多种 Task) 队列中。一旦执行栈为空
众所周知,JS的执行顺序是自上而下的。 严格意义上来说,javascript没有多线程的概念,所有的程序都是单线程依次执行的。 就是代码在执行过程中,另一段代码想要执行就必须等当前代码执行完成后才可以进行。
网站使用了复杂的物理效果和 SVG 滤镜。它在移动设备上的手感很好,所以需要很流畅地运行才能出效果。在同一个线程中运行物理效果和 SVG 滤镜开销太大了,所以我把物理效果部分移动到了 Web Worker 中来充分利用资源。
以前我们总说,JS是单线程没有多线程,当JS在页面中运行长耗时同步任务的时候就会导致页面假死影响用户体验,从而需要设置把任务放在任务队列中;执行任务队列中的任务也并非多线程进行的,然而现在HTML5提供了我们前端开发这样的能力
node.js采用单线程异步非阻塞模式。它的单线程指的是自身Javascript运行环境的单线程,Node.js并没有给Javascript执行时创建新线程的能力,通过Libuv以及它的事件循环来实现异步。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!