ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【JavaScript】Web Worker

2022-02-27 13:32:56  阅读:204  来源: 互联网

标签:postMessage Web console Worker JavaScript worker 线程 监听


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

创建 Worker 对象

let worker = new Worker(jsUrl, options);

第一个参数是一个 JavaScript文件URL —— 这个文件包含了将在 worker 线程中运行的代码。

第二个参数是配置对象,可选——它的一个作用是指定 Worker 的名称,用来区分多个 Worker 线程。

var myWorker = new Worker('worker.js', { name : 'myWorker' });

worker 将运行在与当前 window 不同的另一个全局上下文中,这个上下文由一个对象表示,标准情况下为DedicatedWorkerGlobalScope(标准 workers 由单个脚本使用; 共享workers使用 SharedWorkerGlobalScope)

:你不能直接在 worker 线程中操纵 DOM 元素;或使用 window 对象中的某些方法和属性。大部分 window 对象的方法和属性是可以使用的。

数据通信

主线程和 worker 线程相互之间使用 postMessage() 方法来发送信息, 并且通过 onmessage 这个 event handler来接收信息(传递的信息包含在 Message 这个事件的data属性内) 。

数据的交互方式为传递副本,而不是直接共享数据。

终止 Worker 对象

当 web worker 对象被创建时,它会继续监听消息(即使在外部脚本完成之后)直到它被终止。

如需终止 web worker,并释放浏览器/计算机资源,请使用 terminate() 方法:

worker.terminate();

其他 API

主线程中 Worker 对象的属性和方法如下:

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

Worker 线程中一些自己的全局属性和方法:

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

举例

以下例子来自 MDN

该举例为在后台执行两个数相乘。

注:通常 web worker 不用于这种简单的脚本,而是用于 CPU 密集型任务。例如轮询服务器状态、计算密集型任务等。

  1. 创建 worker 线程执行的 js

监听主线程,接收两个数,返回处理结果:

onmessage = function(e) {
  console.log('Worker: Message received from main script');
  const result = e.data[0] * e.data[1];
  if (isNaN(result)) {
    postMessage('Please write two numbers');
  } else {
    const workerResult = 'Result: ' + result;
    console.log('Worker: Posting message back to main script');
    postMessage(workerResult);
  }
}
  1. 主线程中创建 worker 对象并通信:
const first = document.querySelector('#number1');  
const second = document.querySelector('#number2'); 

const result = document.querySelector('.result'); 

if (window.Worker) { //检查用户的浏览器是否支持worker
  const myWorker = new Worker("worker.js"); //创建 worker 对象

  first.onchange = function() { 
    myWorker.postMessage([first.value, second.value]); //向 Worker 线程发送信息
    console.log('Message posted to worker');
  }

  second.onchange = function() {
    myWorker.postMessage([first.value, second.value]); //向 Worker 线程发送信息
    console.log('Message posted to worker');
  }

  myWorker.onmessage = function(e) { //监听 Worker 线程的信息
    result.textContent = e.data;
    console.log('Message received from worker');
  }
} else {
  console.log('Your browser doesn\'t support web workers.');
}

HTML 页面:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width">

    <title>Web Workers basic example</title>

    <link rel="stylesheet" href="style.css">
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
  </head>

  <body>
    <h1>Web<br>Workers<br>basic<br>example</h1>

    <div class="controls" tabindex="0">
      <form>
        <div>
          <label for="number1">Multiply number 1: </label>
          <input type="text" id="number1" value="0">
        </div>
        <div>
          <label for="number2">Multiply number 2: </label>
          <input type="text" id="number2" value="0">
        </div>
      </form>

      <p class="result">Result: 0</p>
    </div>
    <script src="main.js"></script>
  </body>
</html>

标签:postMessage,Web,console,Worker,JavaScript,worker,线程,监听
来源: https://www.cnblogs.com/hzyuan/p/15942083.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有