zoukankan      html  css  js  c++  java
  • Web Worker 初探

    什么是Web Worker?

    Web Worker 是Html5 提出的能够在后台运行javascript的对象,独立于其他脚本,不会影响页面的性能,也不会影响你继续对于页面进行操作。通俗点讲,就是后台打杂的小工。

    Why Web Worker?

    Javascript 是单线程执行的,即某一时刻,一次只能做一件事情。Javascript的单线程是为了保证对dom操作的统一性,即同一时刻不会既有删除和添加同一个dom的操作,为了保证

    dom树不会混乱,但是单线程执行是对于当下强大的多核CPU的一种浪费,无法充分发挥计算机的性能。为了解决上述问题,就产生了web worker,但是既要满足保证对dom树的统一

    性,又要支持多线程,这就决定了web worker在程序运行时的地位(特性)。

    打个比方,程序的主线程就像是只有一个厨师长的厨房,厨师长要亲自操刀整个做菜流程,配菜,加料等。web worker 就像是厨师长招来的学徒,可以帮忙切菜,帮忙看火候,帮忙调制佐料,但又不会影响整个做菜的主流程(没有权限)。

    所以web worker可以用于负责处理数据,或者执行可以延后的任务。

    如何编写Web Worker

    可以用VSCode 创建一个空白的文件夹,添加index.html,index.js,worker.js等文件。在index.html中引入index.js,接着在index.js中编写如下代码

    function main(){
        let worker = new Worker('worker.js');
        worker.postMessage('start');
        setTimeout(()=>worker.postMessage('end'), 5000);
    
        worker.onmessage = function(event){
            console.log(event.data);
            worker.terminate();
            console.log(worker);
        }
    }
    

    创建一个worker线程,只要通过new 关键字创建一个worker对象就行,传递的参数是woker线程要执行的js脚本,即我们现在给我们的小工分配了工作任务。

    主线程和worker如何通信(厨师长如何给学徒安排任务)

    主线程和worker之间的通信只能通过postMessage 和 onMessage 来进行,主线程通过postMessage来向worker传递信息,worker线程也是通过postMessage来向主线程传递信息,主线程通过onMessage来接收worker传递过来的信息。

    worker线程通过addEventListener('message', callback) 来监听主线程通过postMessage传递的信息。

    下面是一个worker线程的简单例子

    let number = 0;
    let intervalId = 0;
    
    this.addEventListener('message', (e)=>{
        const data = e.data;
        console.log(e.data);
    
        switch(data){
            case 'start':
                this.startCountNumber(); break;
            case 'end':
                this.endCountNumber(); break;
            default:
                break;
        }
    })
    
    function startCountNumber() {
        this.intervalId = setInterval(()=>{number++;console.log(number)}, 1000);
    }
    
    function endCountNumber() {
        clearInterval(this.intervalId);
        self.postMessage('done')
    }

    这是一个用来计数的worker,但是开始结束都由主线程开始,有兴趣的可以改写一下,主线程通知开始任务,当worker完成后,worker通知主线程任务完成。(厨师长安排任务给学徒,学徒做完后通知厨师长)。

    当编写完这两个js文件后,可以通过打开浏览器访问index.html来对这个worker 进行测试。(index.html 不再贴出)

    这里有一个值得注意的点,如果测试的时候是直接打开本地html文件,那么不能用chrome,chrome出于安全问题,会没法加载worker.js(CORS)。换用其它的浏览器即可,或者搭建本地服务器去运行亦可。

    Web Worker注意点

    为什么用厨师长和学徒的例子,就是为了体现web worker的几个注意点。

    1. 学徒无法直接干预厨师长的工作(worker 只能通过postMessage 来向mai'n thread 传递信息)

    2. worker 没法直接读取或者操作dom,也没法使用window,parent等对象,但可以读取navigator, location对象。

    3. web worker加载的脚本必需和主线程脚本同源(厨师长和学徒需要是一个厨房里的)

    4.厨师长可以招多个学徒(主线程可以创建多个worker线程)

    web worker 又分dedicated worker 和shared worker,有兴趣的可以深入了解下。

    以及web worker的错误处理onError, web worker 发送异步请求等。

  • 相关阅读:
    nginx 正向代理 反向代理 负载均衡
    nginx配置文件常用基本配置指令
    92)http 和https协议入门
    tp6--nginx下pathinfo配置
    tp6省略url里的index.php
    echarts鼠标移上去显示数据
    composer 下载thinkphp6失败
    tp5写入cookie失效
    4.15 Spring Cloud理论基础
    4.14 SpringBoot理论基础
  • 原文地址:https://www.cnblogs.com/ChallengeEverything/p/9630894.html
Copyright © 2011-2022 走看看