• javascript实现多线程提升项目加载速度


    以前大家都认为js是单线程执行的,假如我们要执行一些耗时的操作,比如加载一张很大的图片,我们可能需要一个进度条来让用户进行等待,在等待的过程中,整个js线程会被阻塞,后面的代码不能正常运行,这可能大大的降低用户体验,这时候我们就期望拥有一个工作线程来处理这些耗时的操作。在传统的html时代是基本不可能实现的,而现在,我们拥有一种叫做worker的东西。它是js里的一个类,而我们只需要创建它的实例就可以使用它。

    1 var worker = new Worker(js file path);

    构造函数的参数填上你的js文件的路径,这个js文件将会在浏览器新开的线程里运行,而与原先的js引擎的线程并不影响。

    下面看个例子

     1 <!DOCTYPE html>
     2 <html>
     3     <head>
     4         <meta charset="utf-8" />
     5         <title></title>
     6     </head>
     7     <body>
     8         <input type="text" name="ipt" id="ipt" value="" />
     9         <button id="start">start</button>
    10         <button id="stop">stop</button>
    11         <button id="ale">alert</button>
    12         <script type="text/javascript">
    13             var ipt = document.getElementById("ipt");
    14             var stop = document.getElementById("stop");
    15             var start = document.getElementById("start");
    16             var ale = document.getElementById("ale");
    17             var worker = new Worker("js/test22.js");
    18             worker.onmessage = function(){
    19                 ipt.value = event.data;
    20             };
    21             stop.addEventListener("click",function(){
    22                 //用于关闭worker线程
    23                 worker.terminate();
    24             });
    25             start.addEventListener("click",function(){
    26                 //开起worker线程
    27                 worker = new Worker("js/test22.js");
    28             });
    29             ale.addEventListener("click",function(){
    30                 alert("i'm a dialog");
    31             });
    32         </script>
    33     </body>
    34 </html>

    下面是test22.js里的代码,也就是存在于worker线程里的代码

    1 var i = 0;
    2 function mainFunc(){
    3     i++;
    4     //把i发送到浏览器的js引擎线程里
    5     postMessage(i);
    6 }
    7 var id = setInterval(mainFunc,1000);

    运行起来我们会发现

    点击确定后,它的数值并非2,而是一个比2更大的数

    虽然dialog的弹出会阻塞js引擎线程,但是并不影响worker线程的运行,所以,在我们点击确定后,只是在js引擎线程上更新了新的内容,而数值是一直在跑动的,这就说明worker线程和原本的js线程互不影响.

    那么既然互不影响,两个线程之间要怎么来联系呢,答案其实已经在代码里了,那就是onPostMessage 和 onmessage这两个函数,其中onPostMessage(data)的参数是你要传递的数据,而onmessage是一个回调函数,只有在接受到数据时,onmessage会被回调,onmessage有一个隐藏的参数,那就是event,我们可以用event.data获取到传递过来的数据来更新主线程。

    使用worker线程应注意的是,所有js里集成的对象都在js线程里,而并非worker线程。
    例如我们在worker线程里写上:

    1 var a = document.getElementById("a");

    结果你会得到一条Error,告诉你找不到document,或者document is undefined。所以我们尽量把需要的东西都写到主线程里,而只把耗时的操作写到worker线程里。

  • 相关阅读:
    设计模式之迭代器与组合模式(三)
    设计模式之迭代器与组合模式(二)
    设计模式之迭代器与组合模式(一)
    设计模式之模板方法模式(一)
    设计模式之模板方法模式(三)
    设计模式之模板方法模式(二)
    Spring Cloud微服务初探
    设计模式之适配器模式与外观模式(二)
    设计模式之适配器模式与外观模式(一)
    设计模式之命令模式(三)
  • 原文地址:https://www.cnblogs.com/jsonYoung/p/9639185.html
Copyright © 2020-2023  润新知