好玩的web worker

144 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

前言

我们都知道 js是单线程的脚本语言,当在js中产生大量计算或者比较耗时的操作时,会一直占据着主线程,导致UI线程阻塞,影响用户体验。

<div id="home">点击占据主线程</div>
    <div id="test">test
    </div>
    <script>
        document.querySelector("#home").addEventListener('click',()=>{
            for (let index = 0; index < 10000000000; index++) {
            }
            console.log('执行完毕')
        })
       
        document.querySelector('#test').addEventListener("click",()=>{
             alert("test")
        })

    </script>

那什么是web worker呢

MDN:通过使用web worker,web应用程序可以独立于主线程的后台线程中,运行一个脚本操作。这样做的好处就是独立线程中执行费时的处理任务,从而允许主线程(通常是UI线程)不会因此被阻塞/放慢

简而言之就是主线程开了一个子线程,将计算量大或者比较耗时的操作交给子线程来做,做好了再给到主线程就行,这样主线程就能够去做其他事情。

使用web worker改写刚才的例子:

index.html
const work = new Worker('work.js');
        document.querySelector("#home").addEventListener('click', () => {

            work.postMessage("我开始执行了,子线程")

            console.log('执行完毕')
        })

        document.querySelector('#test').addEventListener("click", () => {
            alert("test")
        })
        work.onmessage=(e)=>{
            console.log(e.data)
            worker.terminate()
        }
        
work.js
onmessage=( e)=>{
    for (let index = 0; index < 10000000000; index++) {
    }
  console.log(e.data)
}

动画.gif

知识点介绍

  • postMessage:向worker的内部作用域发送一个消息。
  • onMessage:用于接收发送方发送的信息
  • terminate:用于立即终止 Worker 的行为 ,本方法并不会等待 worker 去完成它剩余的操作;worker 将会被立刻停止

web worker的分类

共享worker

mdn:表示一种可以同时被多个浏览器环境访问的特殊类型的worker。这些浏览器环境可以是多个window,iframes或者是多个worker

个人理解:就是多环境共享某一个worker

例子:

work.js
onconnect = function(e) {
  var port = e.ports[0];
  port.onmessage = function(e) {
    var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
    port.postMessage(workerResult);
  }
}

a.html
<script>
        const awork = new SharedWorker('work.js');
        // awork.port.start();
        awork.port.postMessage([3,3])
        awork.port.onmessage=(e)=>{
             console.log(e.data)//Result: 9
        }
    </script>

index.html
 const indexwork = new SharedWorker('work.js');
        indexwork.port.postMessage([2,3])
        indexwork.port.onmessage=(e)=>{
             console.log(e.data)//Result: 6
        }

知识点介绍

  • SharedWorker:创建一个共享进程的对象
  • start():手动启动端口开始通信;注:使用addEventListener需要,使用on[]时隐式调用
  • conect事件:使用port属性与worker相关的接口连接