zoukankan      html  css  js  c++  java
  • Web Worker

    Web Worker

    JavaScript是单线程语言,如果在Js主线程上进行比较耗时的操作,那么不仅异步的事件回调无法正常完成,浏览器的渲染线程也将被阻塞,无法正常渲染页面。Web Worker能够把JavaScript计算委托给后台线程,线程可以执行任务而不干扰用户界面。

    描述

    worker是使用构造函数创建的一个对象来运行一个Js文件,这个Js文件中包含将在worker线程中运行的代码,worker运行的全局对象不是当前window,专用worker线程运行环境的全局对象为DedicatedWorkerGlobalScope,共享worker线程运行环境的全局对象为SharedWorkerGlobalScope
    worker可以运行任意JavaScript代码,但不能够直接操作DOM节点,也不能使用window对象的默认方法和属性,但是在window对象下的很多方法包括WebSocketsIndexedDB等在worker全局对象中都有实现。
    worker线程与主线程之间的通信是通过postMessage发送消息以及onmessage事件处理函数来接收消息,这个过程中数据并不是被共享而是被复制。
    只要运行在同源的父页面中,worker可以依次生成新的worker。此外worker还可以使用XMLHttpRequest进行网络I/O,但是XMLHttpRequestresponseXMLchannel属性总会返回null

    专用worker

    专用worker仅能被生成它的脚本使用,通过构造函数生成worker,然后通过消息传递机制将数据传递到worker线程计算完毕后再将数据传回进行下一步操作,worker线程的关闭可以在主线程中关闭也可以在worker线程中关闭。

    // 需要开启一个server
    var worker = new Worker('worker.js'); // 实例化worker线程 
    worker.postMessage(1); // 传递消息
    worker.onmessage = function(e){ // 接收消息事件
        console.log(e.data); // 2
        // worker.terminate(); // 关闭worker线程
    }
    
    // worker.js worker线程
    onmessage = function(e) { // worker接收消息
        var v = e.data; 
        console.log(v); // 1
        postMessage(v * 2); // 乘以2并传递消息 // 简单的计算
        // close(); // 关闭worker线程
    }
    

    共享worker

    共享worker可以同时被多个脚本使用,即使这些脚本正在被不同的windowiframe或者worker访问,也就是说可以使用共享worker进行多个浏览器窗口间通信,当然共享worker的通信必须为同源,不能跨域通信。生成共享worker与生成专用worker非常相似,只是构造器的名字不同,他们之间一个很大的区别在于:共享worker必须通过一个确切的打开的端口对象供脚本与worker通信,在专用worker中这一部分是隐式进行的。如果父级线程和worker线程需要双向通信,那么它们都需要调用start()方法,对于消息的传递依然使用postMessage但是必须通过调用端口上的postMessage方法来实现消息通信。

    // 需要开启一个server
    // 页面A 浏览器窗口间通信实例
    var worker = new SharedWorker('worker.js');
    worker.port.start();
    worker.port.postMessage(1);
    
    // 页面B 浏览器窗口间通信实例
    var worker = new SharedWorker('worker.js');
    worker.port.start();
    worker.port.onmessage = function(event){
        console.log(event.data);
    };
    
    // worker.js worker线程
    var portArr = [];
    onconnect = function(e) {
      var port = e.ports[0];
      if(portArr.indexOf(port) === -1) portArr.push(port);
      port.onmessage = function(e) {
        portArr.forEach( v => {
            v.postMessage(e.data);
        })
      }
    }
    

    每日一题

    https://github.com/WindrunnerMax/EveryDay
    

    参考

    https://developer.mozilla.org/zh-CN/docs/Web/API/Worker
    https://developer.mozilla.org/zh-CN/docs/Web/API/SharedWorker
    https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API/Using_web_workers
    
  • 相关阅读:
    LeetCode 230. 二叉搜索树中第K小的元素(Kth Smallest Element in a BST)
    LeetCode 216. 组合总和 III(Combination Sum III)
    LeetCode 179. 最大数(Largest Number)
    LeetCode 199. 二叉树的右视图(Binary Tree Right Side View)
    LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)
    LeetCode 106. 从中序与后序遍历序列构造二叉树(Construct Binary Tree from Inorder and Postorder Traversal)
    指针变量、普通变量、内存和地址的全面对比
    MiZ702学习笔记8——让MiZ702变身PC的方法
    你可能不知道的,定义,声明,初始化
    原创zynq文章整理(MiZ702教程+例程)
  • 原文地址:https://www.cnblogs.com/WindrunnerMax/p/12971738.html
Copyright © 2011-2022 走看看