javascript中的伪线程,使用setTimeout模拟一个多线程

时间: 2018-08-08阅读: 2807标签: 线程

浏览器的内核是多线程的,一个浏览器一般至少实现三个常驻线程: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

站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

链接: http://www.fly63.com/article/detial/999

Node.js中的进程与线程

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。线程(Thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。

浏览器进程线程

进程是正在运行的程序的实例;线程(英语:thread)是操作系统能够进行运算调度的最小单位。可以打开任务管理器,可以看到有一个后台进程列表。这里就是查看进程的地方,而且可以看到每个进程的内存资源信息以及cpu占有率。

nodejs是单线程吗?

node.js采用单线程异步非阻塞模式。它的单线程指的是自身Javascript运行环境的单线程,Node.js并没有给Javascript执行时创建新线程的能力,通过Libuv以及它的事件循环来实现异步。

Js多线程和Event Loop

几乎在每一本JS相关的书籍中,都会说JS是单线程的,JS是通过事件队列(Event Loop)的方式来实现异步回调的。 对很多初学JS的人来说,根本搞不清楚单线程的JS为什么拥有异步的能力,所以,我试图从进程、线程的角度来解释这个问题

浏览器中的 Event Loop

当我们执行 JS 代码的时候其实就是往执行栈中放入函数,那么遇到异步代码的时候该怎么办?其实当遇到异步的代码时,会被挂起并在需要执行的时候加入到 Task(有多种 Task) 队列中。一旦执行栈为空

深入理解 Web Workers

网站使用了复杂的物理效果和 SVG 滤镜。它在移动设备上的手感很好,所以需要很流畅地运行才能出效果。在同一个线程中运行物理效果和 SVG 滤镜开销太大了,所以我把物理效果部分移动到了 Web Worker 中来充分利用资源。

线程的来龙去脉,你了解吗?

用户级线程很快投入使用,Linux系统中的 pthread(POSIX thread)库可以说是大获成功,操作系统做出了一项重大决定——支持内核级线程。内核级线程解决了进程并行的问题,除此之外,由于内核看得到线程的存在

聊聊 JavaScript 与浏览器的那些事 - 引擎与线程

对 JavaScript 解释器和浏览器的线程机制理解的不是特别透彻,很容易混淆浏览器多线程机制并错误认为由于 Web Worker 的设计使得 JavaScript 拥有了多线程的能力。事后搜了不少资料进行学习,整理成此文,主要介绍浏览器的各个引擎、线程间的工作机制以及 JavaScript 单线程的一些事。

如何理解JS的单线程?

JS本质是单线程的。也就是说,它并不能像JAVA语言那样,两个线程并发执行。 但我们平时看到的JS,分明是可以同时运作很多任务的,这又是怎么回事呢?

JavaScript多线程编程

浏览器端JavaScript是以单线程的方式执行的,也就是说JavaScript和UI渲染占用同一个主线程,那就意味着,如果JavaScript进行高负载的数据处理,UI渲染就很有可能被阻断,浏览器就会出现卡顿,降低了用户体验。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!