精华内容
下载资源
问答
  • Web Worker使用方法

    Web Worker特点

    1、利用多核CPU

    2、对多线程支持较好

    注意:

    不能访问HTML页面,不能使用DOM

    主流浏览器基本都支持,除了IE

    如何使用Web Worker

    1、创建Worker文件—就是js文件
    2、判断当前浏览器是否支持Worker
    if(typeof(Worker)!=="undefined"){
    //说明当前浏览器支持Worker
    }else{
    //说明当前浏览器不支持Worker,可以给出说明提示
    }
    3、创建Worker对象—new Worker(worker文件路径)

    小案例:使用worker实现计时器功能
    HTML文件:
    <!DOCTYPE html>
    <html>
     <head>
      <title>Worker的使用入门</title>
      <meta charset="utf-8"/>
     </head>
     <body>
      <button id="start">开始计时</button>
      <button id="stop">结束计时</button>
      <div id="showtime"></div>
      <script>
    // 1. 判断当前浏览器是否支持Web Worker
    if(typeof(Worker) !== "undefined"){
    /*
    * 2. 创建Worker对象
    *  new Worker(Worker文件的路径)
    */
    var worker = new Worker("worker1.js");
    /*
    * 3. 通过Worker对象绑定事件
    *  onmessage事件 - 用于监听Worker文件
    *  * 该事件的处理函数接收参数
    *    * Worker文件通过postMessage()方法传递的消息,可以通过该事件的处理函数的参数进行接收
    */
    worker.onmessage = function(message){
    // 用于接收Worker文件传递的消息
    console.log(message.data);
    }
    }else{
    // 给出相关提示信息
    }
    /*
    * 注意:chrome浏览器在新版本中不再允许读取本地文件
    */
      </script>
     </body>
    </html>

    worker文件:
    var time = 0;
    function showTime(){
    time++;
    // Worker对象的postMessage()方法,传递消息
    postMessage(time);
    }
    showTime();

    4、worker的方法与事件
    方法
    postMessage()—用于向Worker对象传递消息
    terminate()—用于终止Worker的运行
    事件:
    onMessage—监听Worker文件
    当postMessage()方法被触发时,onMessage就被调用
    同时,创建Worker对象时,必须同时绑定onMessage事件

    小案例:使用worker模仿售票系统
    <!DOCTYPE html>
    <html>
     <head>
      <title>使用Worker模拟售票系统</title>
      <meta charset="utf-8"/>
      <style>
    div {
    width : 150px;
    height : 150px;
    border : solid 1px black;
    float : left;
    margin-right : 10px;
    }
      </style>
     </head>
     <body>
      <!-- 模拟售票窗口 -->
      <div id="window0"></div>
      <div id="window1"></div>
      <div id="window2"></div>
      <div id="window3"></div>
      <div id="window4"></div>
      <!--
    需求 - 点击"开始抢票"按钮
    * 有票 - 将对应的div的背景颜色改为绿色
    * 无票 - 将对应的div的背景颜色改为红色
      -->
      <button id="start">开始抢票</button>
      <script>
    var btn = document.getElementById("start");
    var workers = [];//0-4
    btn.onclick = function(){
    // 开始抢票 - worker
    if(typeof(Worker) !== "undefined"){
    for(var i=0;i<5;i++){
    // 创建worker对象
    var worker = new Worker("worker.js");
    // 绑定onmessage事件
    worker.onmessage = myMessage;
    // 将创建的worker对象放置在数组中
    workers[workers.length] = worker;
    }
    }
    }
    /*
    * onmessage事件的处理函数形参(event)
    * * 通过形参获取postMessage()方法传递的消息
    */
    function myMessage(e){
    // 获取worker对象对应的角标
    var index = workers.indexOf(e.target);
    // 获取div对应worker对象 - div的i和worker的i
    var div = document.getElementById("window"+index);
    if(e.data == "1"){
    // 有票
    div.style.background = "green";
    }else{
    // 无票
    div.style.background = "red";
    }
    }
    /*
    * 分析逻辑
    * * 具有5个售票窗口
    *   * 同时开始抢票 - 逻辑相同
    * * 结果
    *   * worker文件只需要创建一个
    *     * 完成抢票逻辑
    *   * 需要创建5个worker对象
    */
      </script>
     </body>
    </html>

    worker.js文件:
    /*
     * Worker文件 - 完成抢票逻辑
     * * 10%概率可以抢到票
     */
    // 生成一个 0-100 之间的一个整数
    var rand = Math.floor(Math.random()*100);
    // 0-99之间,判断概率是10%
    if(rand < 50){
    // 有票
    postMessage(1);
    }else{
    // 无票
    postMessage(0);
    }
    展开全文
  • HTML5之Worker用法

    千次阅读 2011-11-29 12:10:30
    HTML5之Worker用法HTML5提供了Worker类用于多线程处理。Worker是在UI主线程中创建,后台执行的一段js脚本,它通过消息与UI线程传递数据。使用Worker就3步:cheungmine 2011-11-29第1步:创建一个Worker,需要指定一...

    HTML5之Worker用法

    HTML5提供了Worker类用于多线程处理。Worker是在UI主线程中创建,后台执行的一段js脚本,它通过消息与UI线程传递数据。使用Worker就3步:

    cheungmine 2011-11-29

    第1步:创建一个Worker,需要指定一个js文件,作为Worker线程的执行体:

        var worker = new Worker("worker.js");

    第2步:给Worker实例指定消息处理函数,只有2个:onmessage ,onerror
        worker.onmessage = function (event) {
            // update UI here
            var t1 = new Date().getTime();
            elemById("_time").value = t1 - t0;
            elemById("_piValue").value = event.data;
        };

        worker.onerror = function (event) {  
            alert(event.message);  
        };

    第3步:给worker发消息:postMessage。

        elemById("_time").value = "-";
        t0 = new Date().getTime();
        worker.postMessage(parseInt(elemById("_num_rects").value));


    下面以一个具体的例子来说明Worker的用法。这个例子是用数值积分的方法求pi=(3.1415926....)的。worker.js就是做这个工作。


    // worker.js
    //   calculate pi using numerical integration
    // 2011-11, cheungmine
    self.onmessage = function (event) {
      // numerical integration to calc pi
      var num_rects = event.data;
      var width = 1.0/num_rects;
      var mid;
      var height;
      var sum = 0.0;
      var area;
      for (var i=0; i<num_rects; i++) {
    	mid = (i+0.5) * width;
    	height = 4.0/(1.0+mid*mid);
    	sum += height;
      }
      area = width*sum; // area=pi
    
      // post message back to UI thread
      self.postMessage(area);
    };
    
    HTML5主页面js-test.html如下:

    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>js-test.html</title>
      <script type="text/javascript">
        function elemById(id) {
          return document.getElementById(id);
        }
    
        function getBrowserAgent() {
          var browser = "$";
          if ((navigator.userAgent.indexOf('MSIE') >= 0) &&
              (navigator.userAgent.indexOf('Opera') < 0)){
            browser = "$IE";
          }
          else if (navigator.userAgent.indexOf('Firefox') >= 0){
            browser = "$FIREFOX";
          }
          else if (navigator.userAgent.indexOf('Opera') >= 0){
            browser = "$OPERA";
          }
          else if (navigator.userAgent.indexOf('Chrome') >= 0){
            browser = "$CHROME";
          }
          return browser;
        }
    
        var browser = getBrowserAgent();
    
        window.addEventListener('load', 
          function () {
            if (browser=="$IE") {
              // MSIE
              if (window.confirm("IE does not support HTML5 currently.\n"+
                  "please use lastest FireFox, Chrome or Opera!\n"+
                  "if you havenot any of them installed,\n"+
                  "please click OK to enter download page.")) {
                window.location.replace("selbrowser.html");
              }
              else {
                window.close();
              }
            }
            else if (browser=="$FIREFOX"||browser=="$CHROME") {
              // do stuff for FireFox and Chrome
            }
            else {
              // do stuff for others
            }
            
            initPage();
          },
          false
        );
    
    	var dt = new Date();
    	var t0 = 0;
    
        function initPage () {
          // onclick
          elemById("_piWorker").addEventListener('click',
            function(){
              var worker = new Worker("worker.js");
              worker.onmessage = function (event) {
                // update UI here
    			var t1 = new Date().getTime();
    			elemById("_time").value = t1 - t0;
                elemById("_piValue").value = event.data;
              };
    
              worker.onerror = function (event) {  
                alert(event.message);  
              };  
    
    		  elemById("_time").value = "-";
    		  t0 = new Date().getTime();
              worker.postMessage(parseInt(elemById("_num_rects").value));
            },
            false
          );
        }
      </script>
    </head>
    <body>
      <p>Press button "calc" to get pi</p>
      <p>
        <input type="input" size="10" id="_num_rects" value="100000000">
        <input type="button" id="_piWorker" value="calc">
        pi=<input type="input" size="30" id="_piValue" value="">
    	time elapsed: <input type="input" size="10" id="_time" value="-">
      </p>
    </body>
    </html>
    

    如果用户不小心用IE打开了主页面,我们需要提示用户目前IE还干不了这个活,下面的是下载支持HTML5的浏览器页面selbrowser.html:

    <html>
    <head>
      <title>selbrowser.html</title>
    </head>
    <body>
      <p><h4>Download the lastest HTML5 browser!</h4></p>
      <table align="center">
        <tr>
          <td width="200"><a href="http://www.mozilla.org/en-US/firefox/all.html"><h3>Mozilla FireFox</h3></a></td>
          <td width="200"><a href="http://www.google.cn/chrome/eula.html?hl=zh-CN&platform=win"><h3>Google Chrome</h3></a></td>
          <td width="200"><a href="http://www.opera.com/download/"><h3>Opera</h3></a></td>
      </table>
    </body>
    </html>
    

    好,全齐了。把上面3个文件放到同一个目录如:C:/myJSP/test下面:

      test/js-test.html

      test/worker.js

      test/selbrowser.html

    使用FireFox直接打开file:///C:/myJSP/test/js-test.html即可。目前FireFox8不支持http://localhost:8080/myJSP/test/js-test.html,会报Could not load domain错误。

    但是FireFox Aurora支持,只是Worker计算速度超慢。

    目前Chrome不支持Worker直接用file:///C:/myJSP/test/js-test.html方式打开,会报Uncaught Error: SECURITY_ERR: DOM Exception 18

    可以使用Chrome以http://localhost:8080/myJSP/test/js-test.html方式打开。需要建一个本地http server,如tomcat。

    Opera两种方式都支持。









    展开全文
  • Web Worker 用法

    2018-10-22 23:35:07
    一、概述 JavaScript 语言采用的是单线程模型,也就是说,所有任务只能在一个线程上完成,一次只能...Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运...

    一、概述

    JavaScript 语言采用的是单线程模型,也就是说,所有任务只能在一个线程上完成,一次只能做一件事。前面的任务没做完,后面的任务只能等着。随着电脑计算能力的增强,尤其是多核 CPU 的出现,单线程带来很大的不便,无法充分发挥计算机的计算能力。

    Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。

    Web Worker 中的 “Worker” 是指执行代码的并行线程。

    Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。

    Web Worker 有以下几个使用注意点:

    (1)同源限制

    Worker 线程运行的脚本文件,必须和包含主线程脚本文件的文档同源。

    (2)DOM 限制

    Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用documentwindowparent这些对象,这就意味着,并行地修改DOM是不可能的。但是,Worker 线程可以读取navigator对象和location对象。

    (3)通信联系

    Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过异步消息传递机制来实现。

    (4)脚本限制

    Worker 线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。

    (5)文件限制

    Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络

    二、基本用法

    2.1 主线程

    主线程采用new命令,调用Worker()构造函数,新建一个 Worker 线程。

    var worker = new Worker('http://localhost:8088/pages/work.js');
    

    Worker()构造函数的参数是一个脚本文件的url,该文件就是 Worker 线程所要执行的任务。如果url采用的是相对路径,那么是以包含调用 Worker() 构造函数脚本的文档的URL为参照的。而如果指定的URL采用的是绝对路径,那么必须和包含该脚本的文档是同源的。

    由于 Worker 不能读取本地文件,所以这个脚本必须来自网络。如果下载没有成功(比如404错误),Worker 就会默默地失败。

    然后,主线程调用worker.postMessage()方法,向 Worker 发消息,传递给 postMessage() 方法的值会结构性复制。提醒一下,Worker 的 postMessage() 方法和 Window 的 postMessage() 方法是两个不同的东西。

    worker.postMessage('Hello World');
    worker.postMessage({method: 'echo', args: ['Work']});
    

    worker.postMessage()方法的参数,就是主线程传给 Worker 的数据。它可以是各种数据类型,包括二进制数据。

    接着,主线程通过worker.onmessage指定监听函数,接收 Worker线程发回来的消息。

    worker.onmessage = function (event) {
      console.log('Received message ' + event.data);
      doSomething();
    }
    
    function doSomething() {
      // 执行任务
      worker.postMessage('Work done!');
    }
    

    上面代码中,事件对象的data属性可以获取 Worker 发来的数据。

    如果 Worker 抛出了异常,并且它自己没有对其进行捕获和处理,可以作为监听的一个error事件来传递该异常。

    worker.onerror = function (e) { 
      // 记录错误消息日志:包括Worker的文件名和行数
      console.log('Error at ' + e.filename + ': ' + e.lineno + ': ' + e.message);
    }

    Worker 完成任务以后,主线程就可以把Worker线程关掉。

    worker.terminate();
    

    2.2 Worker 线程

    Worker 线程运行在一个全新的js运行环境中,完全和创建Worker的脚本隔离。WorkerGlobalScope 全局对象表示了该新的运行环境。

    Worker 线程内部需要有一个监听函数,监听message事件。

    self.addEventListener('message', function (e) {
      self.postMessage('You said: ' + e.data);
    }, false);
    

    上面代码中,self代表Worker线程自身,即Worker线程的全局对象。因此,等同于下面两种写法。

    // 写法一
    this.addEventListener('message', function (e) {
      this.postMessage('You said: ' + e.data);
    }, false);
    
    // 写法二
    addEventListener('message', function (e) {
      postMessage('You said: ' + e.data);
    }, false);
    

    除了使用self.addEventListener()指定监听函数,也可以使用self.onmessage指定。监听函数的参数是一个事件对象,它的data属性包含主线程发来的数据。self.postMessage()方法用来向主线程发送消息。

    close() 函数允许Worker将自己终止。要注意的是,在Worker对象上没有定义任何API用于检测是否Worker已经将自己关闭,也没有类似onclose这样的事件处理程序属性。如果在一个已经关闭的Worker上调用 postMessage() 方法,那么消息会被无声无息地丢弃,而且也不会有任何错误抛出。因此,如果Worker想要使用 close() 方法将自己关闭,那么最好是先传递诸如“关闭”这样的消息。

    根据主线程发来的数据,Worker 线程可以调用不同的方法,下面是一个例子。

    self.addEventListener('message', function (e) {
      var data = e.data;
      switch (data.cmd) {
        case 'start':
          self.postMessage('WORKER STARTED: ' + data.msg);
          break;
        case 'stop':
          self.postMessage('WORKER STOPPED: ' + data.msg);
          self.close(); // Terminates the worker.
          break;
        default:
          self.postMessage('Unknown command: ' + data.msg);
      };
    }, false);
    

    2.3 WorkerGlobalScope 全局对象

    WorkerGlobalScope 对象是Worker线程的全局对象,它有所有核心js全局对象拥有的那些熟悉,诸如 JSON对象、isNaN() 函数和 Date()构造函数。除此之外,WorkerGlobalScope 对象还有客户端Window对象拥有的一些如下属性:

    • self是对全局对象自身的引用。
    • 计时器方法:setTimeout()、clearTimeout()、setInterval() 以及 clearInterval()。
    • location属性,描述传递给 Worker() 构造函数的URL。和Window对象的location属性一样,此属性指向一个Location对象。该对象有href、protocal、host、hostname、port、pathname、search以及hash属性。在Worker中,这些属性都是只读的。
    • navigator属性,跟 Window.navigator 属性类似。
    • addEventListener() 和 removeEventListener()
    • onerror 属性,可以将它设置为一个错误事件处理程序,错误消息、URL以及行号会作为三个字符串参数传递给该处理程序。如果该处理程序返回false,则表示错误已经处理,不应该再将其当成一个Worker对象上的error事件传播了。

    最后,WorkerGlobalScope 对象还包含客户端js一些重要的构造函数对象。其中包括 XMLHttpRequest(),以及 Worker() 构造函数,Worker可以通过它创建它们自己的Worker线程。

    2.4 Worker 加载脚本

    Worker使用 importScripts() 方法来加载任何需要的库代码。

    // 在开始工作前,先载入需要的类、工具函数
    importScripts('collections/Set.js', 'utils/base64.js');
    

    importScripts() 是一个同步的方法,接受一个或者多个URL参数,每个URL都需指向一个js代码文件。相对地址的URL以传递给 Worker() 构造函数的URL为参照。它会按照指定的顺序依次载入并运行这些js文件。如果载入脚本的时候抛出了网络错误,或者在执行的时候抛出了错误,那么剩下的脚本都不会载入和运行。通过  importScripts() 方法载入的脚本自身还可以调用  importScripts() 方法载入它需要的文件。但是, importScripts() 方法不会试图去跟踪哪些脚本已经载入了,也不会去防止循环依赖的问题。

    三、数据通信

    前面说过,主线程与 Worker 之间的通信内容,可以是文本,也可以是对象。需要注意的是,这种通信是拷贝关系,即是传值而不是传址,Worker 对通信内容的修改,不会影响到主线程。事实上,浏览器内部的运行机制是,先将通信内容串行化,然后把串行化后的字符串发给 Worker,后者再将它还原。

    主线程与 Worker 之间也可以交换二进制数据,比如 File、Blob、ArrayBuffer 等类型,也可以在线程之间发送。下面是一个例子。

    
    // 主线程
    var uInt8Array = new Uint8Array(new ArrayBuffer(10));
    for (var i = 0; i < uInt8Array.length; ++i) {
      uInt8Array[i] = i * 2; // [0, 2, 4, 6, 8,...]
    }
    worker.postMessage(uInt8Array);
    
    // Worker 线程
    self.onmessage = function (e) {
      var uInt8Array = e.data;
      postMessage('Inside worker.js: uInt8Array.toString() = ' + uInt8Array.toString());
      postMessage('Inside worker.js: uInt8Array.byteLength = ' + uInt8Array.byteLength);
    };
    

    但是,拷贝方式发送二进制数据,会造成性能问题。比如,主线程向 Worker 发送一个 500MB 文件,默认情况下浏览器会生成一个原文件的拷贝。为了解决这个问题,JavaScript 允许主线程把二进制数据直接转移给子线程,但是一旦转移,主线程就无法再使用这些二进制数据了,这是为了防止出现多个线程同时修改数据的麻烦局面。这种转移数据的方法,叫做Transferable Objects。这使得主线程可以快速把数据交给 Worker,对于影像处理、声音处理、3D 运算等就非常方便了,不会产生性能负担。

    如果要直接转移数据的控制权,就要使用下面的写法。

    
    // Transferable Objects 格式
    worker.postMessage(arrayBuffer, [arrayBuffer]);
    
    // 例子
    var ab = new ArrayBuffer(1);
    worker.postMessage(ab, [ab]);
    

    四、同页面的 Web Worker(加载本地js路径的Worker)

    通常情况下,Worker 载入的是一个单独的 JavaScript 脚本文件,但是也可以载入与主线程在同一个网页的代码。

    <!DOCTYPE html>
      <body>
        <script id="worker" type="app/worker">
          addEventListener('message', function () {
            postMessage('some message');
          }, false);
        </script>
      </body>
    </html>
    

    上面是一段嵌入网页的脚本,注意必须指定<script>标签的type属性是一个浏览器不认识的值,上例是app/worker

    然后,读取这一段嵌入页面的脚本,用 Worker 来处理。

    var blob = new Blob([document.querySelector('#worker').textContent]);
    var url = window.URL.createObjectURL(blob);
    var worker = new Worker(url);
    
    worker.onmessage = function (e) {
      // e.data === 'some message'
    };
    

    上面代码中,先将嵌入网页的脚本代码,转成一个二进制对象,然后为这个二进制对象生成 URL,再让 Worker 加载这个 URL。这样就做到了,主线程和 Worker 的代码都在同一个网页上面。

    另外一种示例代码:

    // worker线程代码
    let script = `self.onmessage = function (e) { 
      console.log({data: e.data})
      postMessage('我很好!');
    }`;
    
    let workerBlob = new Blob([script], {type: "text/javascript"});
    let url = URL.createObjectURL(workerBlob);
    let worker = new Worker(url);
    worker.postMessage('你好吗?');
    worker.onmessage = function(e) {
        console.log({e})
    }
    worker.onerror = function(error) {
        console.log({error})
    }

    五、实例:Worker 线程完成轮询

    有时,浏览器需要轮询服务器状态,以便第一时间得知状态改变。这个工作可以放在 Worker 里面。

    function createWorker(f) {
      var blob = new Blob(['(' + f.toString() +')()']);
      var url = window.URL.createObjectURL(blob);
      var worker = new Worker(url);
      return worker;
    }
    
    var pollingWorker = createWorker(function (e) {
      var cache;
    
      function compare(new, old) { ... };
    
      setInterval(function () {
        fetch('/my-api-endpoint').then(function (res) {
          var data = res.json();
    
          if (!compare(data, cache)) {
            cache = data;
            self.postMessage(data);
          }
        })
      }, 1000)
    });
    
    pollingWorker.onmessage = function () {
      // render data
    }
    
    pollingWorker.postMessage('init');
    

    上面代码中,Worker 每秒钟轮询一次数据,然后跟缓存做比较。如果不一致,就说明服务端有了新的变化,因此就要通知主线程。

    六、实例: Worker 新建 Worker

    Worker 线程内部还能再新建 Worker 线程(目前只有 Firefox 浏览器支持)。下面的例子是将一个计算密集的任务,分配到10个 Worker。

    主线程代码如下。

    var worker = new Worker('worker.js');
    worker.onmessage = function (event) {
      document.getElementById('result').textContent = event.data;
    };
    

    Worker 线程代码如下。

    // worker.js
    
    // settings
    var num_workers = 10;
    var items_per_worker = 1000000;
    
    // start the workers
    var result = 0;
    var pending_workers = num_workers;
    for (var i = 0; i < num_workers; i += 1) {
      var worker = new Worker('core.js');
      worker.postMessage(i * items_per_worker);
      worker.postMessage((i + 1) * items_per_worker);
      worker.onmessage = storeResult;
    }
    
    // handle the results
    function storeResult(event) {
      result += event.data;
      pending_workers -= 1;
      if (pending_workers <= 0)
        postMessage(result); // finished!
    }
    

    上面代码中,Worker 线程内部新建了10个 Worker 线程,并且依次向这10个 Worker 发送消息,告知了计算的起点和终点。计算任务脚本的代码如下。

    // core.js
    var start;
    onmessage = getStart;
    function getStart(event) {
      start = event.data;
      onmessage = getEnd;
    }
    
    var end;
    function getEnd(event) {
      end = event.data;
      onmessage = null;
      work();
    }
    
    function work() {
      var result = 0;
      for (var i = start; i < end; i += 1) {
        // perform some complex calculation here
        result += 1;
      }
      postMessage(result);
      close();
    }
    

    七、API

    7.1 主线程

    浏览器原生提供Worker()构造函数,用来供主线程生成 Worker 线程。

    var myWorker = new Worker(jsUrl, options);
    

    Worker()构造函数,可以接受两个参数。第一个参数是脚本的网址(必须遵守同源政策),该参数是必需的,且只能加载 JS 脚本,否则会报错。第二个参数是配置对象,该对象可选。它的一个作用就是指定 Worker 的名称,用来区分多个 Worker 线程。

    // 主线程
    var myWorker = new Worker('worker.js', { name : 'myWorker' });
    
    // Worker 线程
    self.name // myWorker
    

    Worker()构造函数返回一个 Worker 线程对象,用来供主线程操作 Worker。Worker 线程对象的属性和方法如下。

    • Worker.onerror:指定 error 事件的监听函数。
    • Worker.onmessage:指定 message 事件的监听函数,发送过来的数据在Event.data属性中。
    • Worker.onmessageerror:指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。
    • Worker.postMessage():向 Worker 线程发送消息。
    • Worker.terminate():立即终止 Worker 线程。

    7.2 Worker 线程

    Web Worker 有自己的全局对象,不是主线程的window,而是一个专门为 Worker 定制的全局对象。因此定义在window上面的对象和方法不是全部都可以使用。

    Worker 线程有一些自己的全局属性和方法。

    • self.name: Worker 的名字。该属性只读,由构造函数指定。
    • self.onmessage:指定message事件的监听函数。
    • self.onmessageerror:指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。
    • self.close():关闭 Worker 线程。
    • self.postMessage():向产生这个 Worker 线程发送消息。
    • self.importScripts():加载 JS 脚本。

    八、利用MessageChannel实现两个 Worker 之间通信

    main.html

    <script>
            var w1 = new Worker("worker1.js");
            var w2 = new Worker("worker2.js");
            var ch = new MessageChannel();
            w1.postMessage("initial port",[ch.port1]);
            w2.postMessage("initial port",[ch.port2]);
            w2.onmessage = function(e){
                console.log(e.data);
            }
    <script>

    worker1.js

    var port;
       onmessage = function(e){
        if(e.data == "initial port"){
            port = e.ports[0];
        }else{
            setTimeout(function(){
                port.postMessage("this is from worker1")
            },2000)
          }
       }

    worker2.js

    var port;
        onmessage = function(e){
        if(e.data == "initial port"){
            port = e.ports[0];
            port.onmessage = function(e){
                postMessage(e.data)
            }
           }
       }

    最终输出:this is from worker1

    传递的路径为:w1=> ch1 => ch2 => w2

    九、兼容性

    IE9+

    参考

     

     

     

     

    展开全文
  • Web Worker用法汇总

    2013-01-29 21:54:29
    HTML5 js后台实现多线程 克服js单线程导致页面卡死情况
  • HEML5 Worker用法笔记

    2017-02-17 11:56:39
    Web Worker的基本原理就是在当前javascript的主线程中,使用Worker类加载一个javascript文件来开辟一个新的线程,起到互不阻塞执行的效果 1.如何使用Worker呢? 首先,我们要知道,Worker提供的接口有哪些: (1

    Web Workers 是 HTML5 提供的一个javascript多线程解决方案,我们可以将一些大计算量的代码交由web Worker运行;Web Worker的基本原理就是在当前javascript的主线程中,使用Worker类加载一个javascript文件来开辟一个新的线程,起到互不阻塞执行的效果

    1.如何使用Worker呢?

    首先,我们要知道,Worker提供的接口有哪些:

    (1)主线程和新线程之间数据交换的接口:postMessage,onmessage。

    实例对象worker.onmessage(function(e){});worker.postMessage(data);

    全局方法onmessage = function(e){};postMessage(data);

    到底怎么使用呢?光说不练,就是混蛋,例子如下:

    //worker.js
    onmessage =function (evt){
      var d = evt.data;//通过evt.data获得发送来的数据

    
    

      comsole.log(d);
      postMessage( "你好,主线程" );//将获取到的数据发送会主线程
    }

    
    
    
    
    
    在html页面中:
    

    
    

    <!DOCTYPE HTML>
    <html>
    <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
     <script type="text/javascript">
        //WEB页主线程
          var worker =new Worker("worker.js");        // 创建一个Worker对象并向它传递将在新线程中执行的脚本的URL,就是上边的worker.js。
             worker.postMessage("你好,子线程");       // 向worker发送数据
             worker.onmessage =function(evt){         // 接收worker传过来的数据函数
                  console.log(evt.data);              // 输出worker发送来的数据
             }
     </script>
     </head>
     <body></body>
    </html>

    WEB主线程:

    1.通过 worker = new Worker( url ) 加载一个JS文件(即子线程)来创建一个worker,同时返回一个worker实例。

    2.通过worker.postMessage( data ) 方法来向worker发送数据。

    3.绑定worker.onmessage方法来接收worker发送过来的数据。

    4.可以使用 worker.terminate() 来终止一个worker的执行。

    worker子线程:

    1.通过postMessage( data ) 方法来向主线程发送数据。

    2.绑定onmessage方法来接收主线程发送过来的数据。



    展开全文
  • 参考博客:Web Worker 使用教程 最简单的demo: main.js var worker = new Worker('/resource/worker.js'); worker.postMessage('Hello World'); worker.onmessage = function (event) { console.log('Received ...
  • html5中的web worker用法

    2016-11-07 21:04:56
    html5 web worker相当于在主线程下有开了一个子线程,可以在...if(typeof(Worker)!=="undefined") { if(typeof(w)=="undefined") {  var w=new Worker("demo_test.js");  work.onmessage=function(event)d {
  • 前言 我们知道js是单线程的,在有时候需要处理一些密集计算或者是高延迟的时候,总会出现不便。而且,现在的cpu都是多核的,单线程也无法充分发挥电脑的计算能力。...小程序中,worker用法主要分为3步(按
  • 需要要使用worker去分担主线程的压力,你可能 需要异步下载,需要解析一些数据,那你首先创建一个worker.js文件。 main.js需要做这件事: function workerStart(){ let worker = new Worker("worker.js"); var ...
  • web worker使用

    2019-06-23 17:32:38
    JavaScript的一个特性就是单...web worker有许多使用上的限制: 1、web worker中无法访问window对象和document对象。 2、和主线程直接的通信只能通过异步消息传递机制来实现。 3、不适宜创建很多的web worker; ...
  • 本文实例讲述了PHP pthreads v3下worker和pool的使用方法。分享给大家供大家参考,具体如下: 有些人会想,明明用thread已经可以很好的工作了,为什么还要搞个worker和pool? 之所以要用到worker和pool还是因为效率...
  • Web Worker使用

    2019-04-02 20:23:04
    Web Workers 是 HTML5 提供的一个...通过使用WebWorker,我们可以在浏览器后台运行Javascript,而不占用浏览器自身线程。WebWorker可以提高应用的总体性能,并且提升用户体验。 有两种WebWorker Webworkers...
  • web worker用法及应用场景

    万次阅读 多人点赞 2018-04-07 11:52:00
    首先简单介绍一下什么是web worker。我们都知道在浏览器中javascript的执行是单线程的,页面上的javascript在执行时会阻塞浏览器的响应,这非常影响用户体验,所以ajax应运而生了。ajax的出现使得页面在等待服务器...
  • service worker使用

    千次阅读 2019-04-18 18:09:55
    Service Workers的使用 背景介绍基本架构Promises同步异步现在来谈谈 Service workers:注册你的 worker ) 背景 有一个困扰 web 用户多年的难题——丢失网络连接。即使是世界上最好的 web app,如果下载不了它,也是...
  • js worker使用总结

    2021-01-18 17:20:37
    文章目录概述一、使用步骤创建worker消息通信销毁worker简单示例二、数据共享三、外部引用四、自动创建五、其他worker使用electron中使用workernodejs中使用worker六、共享worker(SharedWorker)简单使用使用用途七...
  • TP6中GatewayWorker用法

    千次阅读 2020-08-14 17:23:25
    一、参考网站 tp开发手册:... ... 开发手册只介绍了Workman的使用方法,没有介绍GatewayWorker使用方法,通过 composer require topthink/think-worker 安装了workman之后可以看到config目录
  • Web Workers 是 HTML5 提供的...Web Worker的基本原理就是在当前javascript的主线程中,使用Worker类加载一个javascript文件来开辟一个新的线程,起到互不阻塞执行的效果,并且提供主线程和新线程之间数据交换的接口:
  • Web Worker 使用指南

    2020-02-20 23:31:16
    Web Worker 是 HTML5 新出的标准。...在 JavaScript 中,主线程可以创建多个 Worker 子线程。Worker 子线程不影响主线程的执行,也就是不影响页面交互,只在后台运行,等到计算完成,再把结果返回给主线程。
  • webWorker使用积累

    2021-06-30 09:32:37
    框架中使用webWorker由于webWorker不能直接读取ts,而js 文件受限不能import或require模块,一般使用worker-loader.d.ts文件,将.ts的webworker文件导出。但由于框架受限不能直接获取(本人学艺不精)也可以直接再....
  • 页面资产的缓存优先方法可加快页面加载速度 CMS和目录页面的离线缓存,允许在网络状况不佳的情况下查看以前访问的页面 安装 使用Composer将此扩展添加到您的Magento安装中: composer require meanbee/magento2-...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 150,682
精华内容 60,272
关键字:

worker的用法