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

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

浏览器的内核是多线程的,一个浏览器一般至少实现三个常驻线程: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.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

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

关闭

浏览器中的 Event Loop

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

如何理解JS的单线程?

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

Web Workers 到底是什么?

以前我们总说,JS是单线程没有多线程,当JS在页面中运行长耗时同步任务的时候就会导致页面假死影响用户体验,从而需要设置把任务放在任务队列中;执行任务队列中的任务也并非多线程进行的,然而现在HTML5提供了我们前端开发这样的能力

Node.js 多线程完全指南

很多人都想知道单线程的 Node.js 怎么能与多线程后端竞争。考虑到其所谓的单线程特性,许多大公司选择 Node 作为其后端似乎违反直觉。要想知道原因,必须理解其单线程的真正含义。

Js多线程和Event Loop

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

理解的线程、进程的关系与区别

进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,进程包含多个线程在运行。一简言之: 进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,进程包含多个线程在运行。

理解JS执行顺序

众所周知,JS的执行顺序是自上而下的。 严格意义上来说,javascript没有多线程的概念,所有的程序都是单线程依次执行的。 就是代码在执行过程中,另一段代码想要执行就必须等当前代码执行完成后才可以进行。

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

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

JavaScript Event Loop和微任务、宏任务

JavaScript的一大特点就是单线程, 同一时间只能做一件事情,主要和它的用途有关, JavaScript主要是控制和用户的交互以及操作DOM。注定它是单线程。 假如是多个线程, 一个移除DOM节点,一个新增DOM节点,浏览器以谁的为准呢?

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

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

点击更多...

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