您现在的位置是:首页 > 技术教程 正文

Web Worker简介和使用

admin 阅读: 2024-03-29
后台-插件-广告管理-内容页头部广告(手机)
1、Web Worker简介

JavaScript 是一种单线程语言,这意味着在一个页面中,所有的 JavaScript 代码都在同一个线程中运行。在单线程模型中,所有任务都是按顺序执行的,如果某个任务需要花费较长时间才能完成,它将阻塞其他任务的执行。HTML5 引入了 Web Workers技术,允许在浏览器中创建多个 JavaScript 线程,以便在后台执行计算密集型任务,从而避免阻塞主线程。Web Worker 是一个独立的 JavaScript 程序,它运行在与主线程不同的上下文中,并且与主线程是完全独立的, 可以运行长时间运算、处理大量数据或与服务器通信等任务,而不会阻塞页面的用户界面。

下面是 Web Worker 的几个优点:

  • 提高页面性能:Web Worker 可以在后台线程中执行一些计算密集型或者耗时的操作,如数据处理、图像处理等,而不会占用主线程,从而避免了页面卡顿或者卡死的情况,提高了页面的性能和响应速度。

  • 可以处理大规模数据:Web Worker 可以处理大规模的数据,因为它们在单独的线程中运行,不会影响主线程的运行,可以更高效地处理大规模的数据,提高了代码的效率和可扩展性。

  • 可以使代码更加模块化:使用 Web Worker,可以将代码分割成多个模块,分别运行在不同的线程中,从而使得代码更加模块化,可维护性和可读性更强。

  • 支持多线程:Web Worker 支持多线程,因此可以利用多核处理器的优势,提高代码的运行效率。

2、Web Worker的创建和使用
2.1 创建 Worker

在主线程中使用new Worker()构造函数来创建一个新的Worker对象,例如:

const worker = new Worker('worker.js');
  • 1

这里的 worker.js 是一个独立的 JavaScript 文件,它将作为 Worker 的入口点。当创建 Worker 实例时,浏览器会将 worker.js 文件加载到一个独立的执行环境中,并开始运行它。

2.2 发送消息

以使用Worker对象的postMessage()方法向工作线程(worker.js)发送消息。例如:

worker.postMessage('Hello, worker!');
  • 1
2.3 在工作线程(worker.js)中处理消息

在工作线程worker.js中,您可以使用onmessage事件监听器来接收来自主线程的消息,并使用postMessage()方法向主线程发送消息。例如:

onmessage = function(e) { console.log('Message received from main thread:', e.data); postMessage('Hello, main thread!'); }
  • 1
  • 2
  • 3
  • 4

这里的onmessage函数将在主线程发送消息时被调用,并将“Hello, main thread!”发送回主线程。

2.4 监听消息事件

在主线程中,可以使用onmessage事件监听器来接收来自工作线程的消息。例如:

Worker.onmessage = function(e) { console.log('Message received from worker:', e.data); }
  • 1
  • 2
  • 3
2.5 Web Worker 的关闭

当你使用 Web Worker 时,它会占用一定的系统资源,如内存等。如果你创建了太多的 Worker,或者没有关闭它们,会导致系统资源的消耗,从而影响整个应用程序的性能。因此,为了避免资源泄漏和提高系统性能,我们应该在不再需要使用 Worker 的时候及时关闭它们。可以使用 Worker.terminate() 方法来关闭一个 Web Worker。

// 关闭Web Worker worker.terminate();
  • 1
  • 2
2.6 worker.js文件加载引用
  • 使用在html中引用 worker.js文件

    <!-- 将worker.js文件包含在HTML--> <script src="worker.js"></script>
    • 1
    • 2
  • 在javascript代码中直接引用

    <!-- worker.js和主程序在同一文件夹下 --> const worker = new Worker('worker.js'); <!-- worker.js和主程序不在同一文件夹下 --> const worker = new Worker('../resource/fundids/js/worker_diff.js'); 3
    • 1
    • 2
    • 3
    • 4
  • worker.js中加载其他JavaScript代码
    在Web Worker中,您不能直接访问页面中的DOM元素和JavaScript对象。如果您的Web Worker需要访问其他JavaScript代码,您可以使用importScripts()方法加载它们。importScripts()方法可以接受一个或多个参数,这些参数是需要加载的JavaScript文件的URL。在加载这些文件时,它们将立即被执行,并且在Web Worker的全局作用域中定义的所有变量和函数都将在Web Worker中可用。

    以下是一个示例,演示了如何在Web Worker中使用importScripts()方法加载其他JavaScript代码:

    // 在这里可以使用在file1.js和file2.js中定义的变量和函数 importScripts("file1.js", "file2.js");
    • 1
    • 2
2.5 使用Web Worker实例
DOCTYPE html> <html> <head> <title>Web Worker 斐波那契数列title> <script> // 创建一个新的 Web Worker,指定 worker.js 文件作为代码文件 const worker = new Worker('worker.js'); // 向 Web Worker 发送一个消息 worker.postMessage(100); // 监听 Web Worker 返回的结果 worker.onmessage = function(event) { console.log('斐波那契数列:', event.data); var resultElement = document.getElementById("result"); resultElement.innerHTML += ""+event.data+""; }; script> head> <body> <h1>Web Worker Exampleh1> <div id="result">div> body> html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

在 worker.js 文件中,我们可以实现计算斐波那契数列的代码:

// 监听来自主线程的消息 onmessage = function(event) { const n = event.data; var result = fibonacciArray(n); // 将结果发送回主线程 postMessage(result); }; // 计算斐波那契数列 function fibonacciArray(n) { var fib = [1, 1]; // 前两个数字是1 for (var i = 2; i < n; i++) { fib[i] = fib[i-1] + fib[i-2]; // 计算下一个数字并添加到数组中 } return fib; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在这个示例中,我们使用了一个 Web Worker 来计算斐波那契数列。当主线程向 Web Worker 发送一个消息时,Web Worker 开始计算斐波那契数列,并将结果发送回主线程。由于计算斐波那契数列可能需要一些时间,因此使用 Web Worker 可以避免阻塞主线程,从而提高页面性能和用户体验。

3、web worker缺陷
  1. 无法直接访问 DOM:由于 Web Worker 运行在独立的线程中,不能直接访问主线程中的 DOM,因此需要使用特殊的方式进行通信,如 postMessage() 方法。

  2. 无法访问主线程中的 JavaScript 对象:Web Worker 独立运行在一个线程中,无法直接访问主线程中的 JavaScript 对象,需要使用序列化和反序列化等技术进行数据传递。

  3. 无法加载本地文件:Web Worker 只能通过网络加载 JavaScript 文件,无法直接加载本地文件。

  4. 无法执行同步操作:Web Worker 无法执行同步操作,如读取文件或等待用户的输入等,因为同步操作会阻塞 Web Worker 的线程。

  5. 不支持所有浏览器:Web Worker 不是所有浏览器都支持,尤其是一些旧版的浏览器可能不支持 Web Worker。

    if (typeof(Worker) !== "undefined") { // 支持webworker }
    • 1
    • 2
    • 3
4、Web Worker与后端传输数据

Web Worker 不能直接访问主线程中的 DOM。这意味着 Web Worker 不能直接操作页面的 HTML 元素或修改浏览器的 URL。但是,Web Worker 可以使用 XMLHTTPRequest 和 Fetch API 等技术从服务器获取数据,并通过消息传递机制将数据发送给主线程。

4.1 使用XMLHttpRequest
// 监听从主线程发送来的消息 onmessage = function(event) { var data = event.data; var newData = []; for (var i = 0; i < data.length; i++) { _add(data[i]); }; }; function _add(d,flag) { var num1 = d.num1; var num2 = d.num2; var id = d.id; // 创建 XMLHttpRequest 对象 var xhr = new XMLHttpRequest(); // 监听请求状态变化事件 xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { // 请求成功 result = {"id":id, "num1":num1, "num2":num2, "result":xhr.responseText}; postMessage(result); } }; // 发送 AJAX 请求 xhr.open("POST", "/test/WebWorkers/add_ajax.tsl", true); // 打开请求连接 // xhr.setRequestHeader("Content-type", "application/json"); // 设置请求头 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // var data = {dowhat:'add', num1:num1, num2:num2}; // 定义要发送的数据并转换为 JSON 字符串 // xhr.send(JSON.stringify(data)); // 发送数据 var data = new URLSearchParams(); data.append("num1",num1); data.append("num2",num2); xhr.send(data); // 发送数据 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
4.2 Fetch API
function _add2(d){ var num1 = d.num1; var num2 = d.num2; var id = d.id; //var data = new URLSearchParams(); var formData = new FormData(); formData.append("num1",num1); formData.append("num2",num2); fetch("/test/WebWorkers/add_ajax.tsl", { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { result = {"id":id, "num1":num1, "num2":num2, "result":data}; postMessage(result); }) .catch(error => console.error(error)) }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

FormData是一种用于处理表单数据的JavaScript API,它可以通过XMLHttpRequest或fetch()方法发送表单数据到后端服务器。FormData对象包含一个键值对列表,可以用于构建表单数据。可以使用FormData对象的append()方法向FormData对象添加键值对。
如上使用了FormData()以表单的形式提交数据,后端即可直接Q(“name”)获取数据,如果提交不同格式的数据,如json串等,当前后端获取前端参数的方法可能不支持。

6、应用场景

Web Worker 的一些应用场景:

  1. 图像处理:在 Web 应用程序中,经常需要对图片进行处理、缩放、剪裁等操作。这些操作可能会消耗大量的 CPU 时间和内存资源,导致页面变卡。使用 Web Worker 可以将这些计算密集型任务放到后台线程中执行,避免阻塞主线程。
  2. 数据计算:对于大规模的数据集,需要进行复杂的计算和数据分析,例如数据挖掘、机器学习、人工智能等。这些任务需要大量的计算资源和时间,使用 Web Worker 可以将计算任务分散到多个线程中,加快计算速度。
  3. 后台请求:在 Web 应用程序中,可能需要进行一些后台请求和数据处理,例如与服务器进行交互、读写文件等。使用 Web Worker 可以将这些任务放到后台线程中执行,避免阻塞主线程,提高应用程序的性能和响应速度。
  4. 多媒体处理:在 Web 应用程序中,经常需要对音频、视频等多媒体资源进行处理和转码,这些任务需要大量的计算资源和时间。使用 Web Worker 可以将这些任务放到后台线程中执行,避免阻塞主线程。

需要注意的是,Web Worker 并不是适用于所有场景的解决方案。对于一些简单的任务,使用 Web Worker 可能会增加代码复杂度,并且可能会带来额外的开销和性能问题。因此,在应用 Web Worker 时需要根据具体情况进行评估和选择。

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索