• 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 发送异步请求等。

  • 相关阅读:
    【学习总结】Git学习-参考廖雪峰老师教程二-安装Git
    【学习总结】Git学习-参考廖雪峰老师教程一-Git简介
    【学习总结】vi/vim命令是使用
    【学习总结】Git学习-参考廖雪峰老师教程-总
    【kindle笔记】之 《鬼吹灯》-9-20
    【学习总结】win7下安装Ubuntu双系统的日常
    【kindle笔记】之 《明朝那些事儿》-2018-7-1
    【kindle笔记】之 《黑客微百科》-2018-6-17
    【kindle笔记】之 《恶意》-2018-4-20
    【kindle笔记】之 《活着》-2018-2-5
  • 原文地址:https://www.cnblogs.com/ChallengeEverything/p/9630894.html
Copyright © 2020-2023  润新知