Web Worker简介和使用
后台-插件-广告管理-内容页头部广告(手机) |
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缺陷
-
无法直接访问 DOM:由于 Web Worker 运行在独立的线程中,不能直接访问主线程中的 DOM,因此需要使用特殊的方式进行通信,如 postMessage() 方法。
-
无法访问主线程中的 JavaScript 对象:Web Worker 独立运行在一个线程中,无法直接访问主线程中的 JavaScript 对象,需要使用序列化和反序列化等技术进行数据传递。
-
无法加载本地文件:Web Worker 只能通过网络加载 JavaScript 文件,无法直接加载本地文件。
-
无法执行同步操作:Web Worker 无法执行同步操作,如读取文件或等待用户的输入等,因为同步操作会阻塞 Web Worker 的线程。
-
不支持所有浏览器: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 的一些应用场景:
- 图像处理:在 Web 应用程序中,经常需要对图片进行处理、缩放、剪裁等操作。这些操作可能会消耗大量的 CPU 时间和内存资源,导致页面变卡。使用 Web Worker 可以将这些计算密集型任务放到后台线程中执行,避免阻塞主线程。
- 数据计算:对于大规模的数据集,需要进行复杂的计算和数据分析,例如数据挖掘、机器学习、人工智能等。这些任务需要大量的计算资源和时间,使用 Web Worker 可以将计算任务分散到多个线程中,加快计算速度。
- 后台请求:在 Web 应用程序中,可能需要进行一些后台请求和数据处理,例如与服务器进行交互、读写文件等。使用 Web Worker 可以将这些任务放到后台线程中执行,避免阻塞主线程,提高应用程序的性能和响应速度。
- 多媒体处理:在 Web 应用程序中,经常需要对音频、视频等多媒体资源进行处理和转码,这些任务需要大量的计算资源和时间。使用 Web Worker 可以将这些任务放到后台线程中执行,避免阻塞主线程。
需要注意的是,Web Worker 并不是适用于所有场景的解决方案。对于一些简单的任务,使用 Web Worker 可能会增加代码复杂度,并且可能会带来额外的开销和性能问题。因此,在应用 Web Worker 时需要根据具体情况进行评估和选择。
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。
在线投稿:投稿 站长QQ:1888636
后台-插件-广告管理-内容页尾部广告(手机) |