HTML5新特性 多线程(Worker SharedWorker)

HTML5引入了多线程的概念,允许在单个页面中使用多个线程执行JavaScript代码。其中,Worker和SharedWorker是两种用于实现多线程编程的JavaScript API,它们可以在后台线程中执行JavaScript代码,而不会阻塞页面的渲染和交互。本教程就为大家详细介绍HTML5的多线程新特性及Worker和SharedWorker的使用方法。

HTML5多线程

HTML5的多线程可以提高网页的响应速度和性能。通常情况下,JavaScript的执行是单线程的,所有的操作都在一个线程中完成,这就导致了当页面上的JavaScript代码执行时间过长时,会阻塞页面的渲染和交互,影响用户体验。

而使用HTML5的多线程功能,可以将一些比较耗时的操作放在后台线程中进行处理,不会阻塞页面的渲染和交互。这样就可以保证页面的正常显示和用户的响应速度。

Worker

Worker是HTML5新特性中用于实现多线程编程的API之一。Worker可以在后台线程中执行JavaScript代码,而且可以与页面的主线程进行通信,实现数据的传输和共享。

创建Worker:

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

Worker的构造函数需要传入一个JavaScript文件(worker.js),该文件中的代码将在一个新的线程中运行,在主线程中能够通过worker对象实现与该线程的交互和通信。

在worker.js中,可以使用一些全局的API和方法,例如addEventListener、removeEventListener等,但是无法访问DOM对象或者其他JavaScript对象。worker.js中的代码将在一个单独的上下文中运行,不会对页面上的其他代码产生影响。

// worker.js
console.log('Worker is running');

self.addEventListener('message', function(e) {
  // 接收消息
  console.log('Worker received message:', e.data);
  // 发送消息回主线程
  self.postMessage('Hello from Worker!');
}, false);

在Worker线程中,可以通过self对象实现对于自身线程的控制和通信。在上面的例子中,我们通过addEventListener方法监听message事件,接受主线程发送的消息;然后使用postMessage方法把消息发送回主线程。

在主线程中,可以监听Worker的message事件来接收Worker发送的消息:

var worker = new Worker('worker.js');
worker.addEventListener('message', function(e) {
  // 接收Worker发送的消息
  console.log('Main thread received message:', e.data);
}, false);
// 发送消息到Worker
worker.postMessage('Hello from main thread!');

在上面的代码中,我们使用addEventListener方法监听Worker对象的message事件,当Worker发送消息时,就会触发该事件,我们可以在事件回调函数中通过e.data属性获取Worker发送的数据。

SharedWorker

SharedWorker是与Worker类似的HTML5多线程API,它也可以在后台线程中执行JavaScript代码,但是与Worker不同的是,SharedWorker可以被多个页面共享,实现多个页面之间的通信和数据共享。

创建SharedWorker:

var sharedWorker = new SharedWorker('shared-worker.js');

与Worker对象一样,SharedWorker的构造函数需要传入一个JavaScript文件名(shared-worker.js),该文件中的代码会在一个新的线程中执行,并在多个页面之间共享数据和通信。

// shared-worker.js
console.log('SharedWorker is running');

var connections = []; // 存储每个连接的页面
self.addEventListener('connect', function(e) {
  var port = e.ports[0]; // 获取端口
  connections.push(port); // 存储端口
  console.log('SharedWorker is connected to a page.');

  port.addEventListener('message', function(e) {
    console.log('SharedWorker received message from a page:', e.data);
    // 把消息发送到其他连接的页面
    connections.forEach(function(connection) {
      if (connection !== port) {
        connection.postMessage(e.data);
      }
    });
  }, false);

  port.start(); // 启动端口
});

在SharedWorker的JavaScript文件中,我们可以使用connect事件来监听与页面之间的连接,并在连接建立之后,通过端口(port)来执行与页面之间的通信。

在上面的代码中,我们定义了一个connections数组,它用于存储所有连接的页面的端口信息。当页面建立连接时,SharedWorker会获取该页面的端口,并把端口存储到connections数组中。然后,SharedWorker会在端口上添加message事件,监听该页面发送的消息,并且将接收到的消息发送给其他连接的页面。

在主页面中,我们可以通过SharedWorker对象连接到SharedWorker线程,并进行通信:

var sharedWorker = new SharedWorker('shared-worker.js');
sharedWorker.port.addEventListener('message', function(e) {
  console.log('Main page received message from SharedWorker:', e.data);
}, false);
sharedWorker.port.start();

sharedWorker.port.postMessage('Hello from main page');

在上面的代码中,我们通过SharedWorker对象获取端口(port),并监听端口的message事件,当SharedWorker发送消息时,就会触发该事件。主页面可以通过port.postMessage方法发送消息到SharedWorker,并且也可以在SharedWorker线程中与其他页面进行数据传输和通信。

示例说明

下面我们通过两个示例来说明Worker和SharedWorker的用法:

示例1:Web Worker

在这个示例中,我们通过Worker对象计算斐波那契数列,以便展示Worker线程对于页面渲染的影响。

<p>计算斐波那契数列:</p>
<input type="number" id="number">
<button id="calculate">计算</button>
<p id="result"></p>

<script>
function fibonacci(n) {
  if (n < 2) {
    return n;
  } else {
    return fibonacci(n-1) + fibonacci(n-2);
  }
}

var button = document.getElementById('calculate');
button.addEventListener('click', function() {
  var number = document.getElementById('number').value;
  var startTime = new Date().getTime(); // 记录开始时间

  var worker = new Worker('worker.js'); // 创建Worker线程
  worker.addEventListener('message', function(e) {
    document.getElementById('result').innerHTML = '第 ' + number + ' 个斐波那契数列:' + e.data;
    var endTime = new Date().getTime(); // 记录结束时间
    console.log('Spent time:', endTime - startTime, 'ms');
  }, false);
  worker.postMessage(number); // 向Worker发送消息计算斐波那契数列
}, false);
</script>

在这个代码中,我们定义了一个计算斐波那契数列的函数fibonacci,并给页面添加了一个输入框和一个计算按钮。当用户输入一个数字并点击计算按钮时,就创建一个Worker对象,并且向Worker线程发送消息让它计算斐波那契数列。

以下是worker.js中斐波那契数列的计算过程:

// worker.js
function fibonacci(n) {
  if (n < 2) {
    return n;
  } else {
    return fibonacci(n-1) + fibonacci(n-2);
  }
}
self.addEventListener('message', function(e) {
  var result = fibonacci(e.data); // 计算斐波那契数列
  self.postMessage(result); // 向主线程发送消息
}, false);

在worker.js中,我们使用addEventListener方法监听message事件,在接收到主线程发送的消息时,调用斐波那契数列计算函数,并把结果发送回主线程。

示例2:Shared Worker

在这个示例中,我们使用SharedWorker对象和Web Socket来实现一个在线聊天室。

以下是聊天室页面的HTML代码:

<p>欢迎来到聊天室:</p>
<input type="text" id="input">
<button id="send">发送</button>
<ul id="messages"></ul>

<script>
var sharedWorker = new SharedWorker('shared-worker.js'); // 创建SharedWorker

sharedWorker.port.addEventListener('message', function(e) {
  var message = document.createElement('li');
  message.textContent = e.data;
  document.getElementById('messages').appendChild(message);
}, false);
sharedWorker.port.start();

var input = document.getElementById('input');
var sendButton = document.getElementById('send');
sendButton.addEventListener('click', function() {
  var message = input.value;
  sharedWorker.port.postMessage(message); // 发送消息到SharedWorker
  input.value = '';
}, false);
</script>

在这个代码中,我们定义了一个输入框和发送按钮,当用户输入一条消息并点击发送按钮时,就通过SharedWorker对象把消息发送给其他连接的页面。

以下是shared-worker.js中处理消息的代码:

// shared-worker.js
var connections = []; // 存储每个连接的页面
self.addEventListener('connect', function(e) {
  var port = e.ports[0]; // 获取端口
  connections.push(port); // 存储端口

  port.addEventListener('message', function(e) {
    // 把消息发送到其他连接的页面
    connections.forEach(function(connection) {
      if (connection !== port) {
        connection.postMessage(e.data);
      }
    });
  }, false);

  port.start(); // 启动端口
});

在shared-worker.js中,我们使用connect事件来监听连接事件,并在建立连接之后,把端口存储到connections数组中。然后,通过端口的message事件监听每个连接的消息,接收到消息后,就把消息发送给connections数组中的其他连接。

好了,这就是关于HTML5的多线程新特性和Worker、SharedWorker的详细介绍,希望能对大家有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:HTML5新特性 多线程(Worker SharedWorker) - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Linux/Unix操作系统目录结构的来历

    Linux/Unix操作系统目录结构的来历: Linux/Unix操作系统目录结构的设计最初是基于多用户,多任务的操作系统。在早期的操作系统中,只有很少的目录和文件需要进行管理,但是随着操作系统的发展,需要管理的目录和文件数量不断增加,这就需要一种更为完善的结构来管理这些文件和目录。而Linux/Unix操作系统目录结构的设计正是为了应对这一需求而产生的。 …

    other 2023年6月27日
    00
  • php使用mysqli和pdo扩展,测试对比mysql数据库的执行效率完整示例

    PHP使用mysqli和pdo扩展,测试对比MySQL数据库的执行效率完整示例攻略 1. 准备工作 在开始测试之前,确保您已经安装了PHP、MySQL数据库,并且已经启用了mysqli和pdo扩展。 2. 创建测试数据库和表 首先,创建一个名为testdb的数据库,并在其中创建一个名为users的表,用于测试。 CREATE DATABASE testdb;…

    other 2023年10月18日
    00
  • MyBatis 接收数据库中没有的字段的解决

    MyBatis是一种优秀的持久层框架,它可以很好地解决Java应用程序中与数据库打交道的操作,支持SQL编写和ORM框架两种开发方式。然而有时候我们会碰到数据库表中新增了字段,但对应的Java实体类没有相应更新的情况,那么我们该如何在MyBatis中处理这种情况呢?下面是针对这种情况的完整攻略。 解决方案 方案一:在查询语句中手动忽略掉没有的字段 我们可以在…

    other 2023年6月25日
    00
  • 在sklearn中需要train_test_split的random_state

    在sklearn中需要train_test_split的random_state的完整攻略 在sklearn中,train_test_split是一个常用的函数,用于将数据集划分为训练集和测试集。其中,random_state是一个可选参数,用于控制数据集的随机。本攻略将详细讲解在sklearn需要train_test_split的random_state的…

    other 2023年5月7日
    00
  • java获取文件扩展名的方法小结【正则与字符串截取】

    Java获取文件扩展名的方法小结【正则与字符串截取】 在Java中,获取文件扩展名的方法有多种。本文将介绍两种常用的方法:正则表达式和字符串截取。 方法一:正则表达式 使用正则表达式可以方便地从文件名中提取出扩展名。下面是一个示例代码: import java.util.regex.Matcher; import java.util.regex.Patter…

    other 2023年8月6日
    00
  • telegram代理工具——mtproxy(mtprotoproxy)

    以下是关于Telegram代理工具mtproxy(mtprotoproxy)的完整攻略,包括mtproxy的定义、工作原理、安装和配置方法、示例说明和注意事项。 mtproxy的定义 mtproxy是一种Telegram代具,用于在网络环境受限的情况下访问Telegram。它是一种基于MTProto协议的代理工具,可以提供更快的速度和更好的安全性。 mtpr…

    other 2023年5月8日
    00
  • Android开发笔记之Android中数据的存储方式(二)

    Android开发笔记之Android中数据的存储方式(二) 在Android开发中,数据的存储是一个非常重要的话题。在上一篇文章中,我们介绍了Android中数据的存储方式之一,即使用SharedPreferences。在本篇文章中,我们将继续探讨Android中的其他数据存储方式。 1. 使用文件存储数据 Android中可以使用文件来存储数据。下面是一…

    other 2023年9月7日
    00
  • React Hook用法示例详解(6个常见hook)

    首先需要明确的是React Hook是React16.8中加入的新特性,它可以让我们在不编写类的情况下使用state和其他React特性。 下面分别介绍React Hook中的6个常见hook及其用法示例: 1.useState import React, { useState } from ‘react’; function Example() { con…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部