前端多线程之Worker

本文介绍了Web Worker的使用,通过一个简单的中国象棋AI运算的场景,展示了如何在主线程与Worker线程间传递数据,进行计算并返回结果,以此提升前端的计算性能,避免页面卡顿,提供更好的用户体验。
摘要由CSDN通过智能技术生成

前言

首先,我们都知道前端js所在的运行环境是一个单线程环境,即同一时刻只能执行一段代码,无法实现并行处理的操作,比如异步编程。但是这并不绝对,Worker 可以使得我们创建另外一个后台线程为我们服务,相信大多数朋友可能对于Worker接口都比较陌生,大家可以先去MDN官网查看文档:Worker文档

Worker的使用流程

  1. 主线程创建Worker对象
  2. 给Worker对象绑定message监听事件,监听新线程传递的信息
  3. 给新线程的self对象绑定message监听事件,监听主线程传递的信息
  4. 两线程之间通过postMessageAPI传递数据

self是当前window对象的一个引用,详见文档:self文档
postMessage可以进行不同页面脚本间的通信,详见文档:postMessage文档

简单的demo

Talk is cheap,show you my demo!
这个demo我们需要准备三个文件:demo.html,worker.js以及self.js。
这个demo模拟的功能是主线程每次会给新线程传递一个0-9的随机数,然后新线程会在一秒后进行传入的数据进行平方操作并返回给主线程。
worker.js是配置主线程相关的信息:(创建新线程以及为Worker对象添加监听事件)

const worker = new Worker('self.js');
worker.onmessage = (e) => {
    const data = e.data
    console.log('Received self message:' + data);
}
function work() {
    worker.postMessage(Math.floor(Math.random() * 10));
}

window.start = work;

self.js是配置新线程相关的信息:(给self对象添加监听事件)

self.onmessage = (e) => {
    const data = e.data;
    console.log('worker data:' + data);
    timedCount(data);
}

function timedCount(data) {
    setTimeout(() => {
        console.log('计算一秒')
        self.postMessage(data ** 2);
    }, 1000);
}

至于demo.html,是因为此程序只能在浏览器中允许并且需要启动Live Serve:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    demo test
    <script src="./worker.js"></script>
</body>
</html>

允许此demo,再控制台中输入start(),即可看到如下结果:
在这里插入图片描述

demo的使用场景

主线程给子线程传递数据,子线程加工数据,经过一段时间后将结果返回给主线程,其实这种设计思想可以运用在前端ai设计上,比如中国象棋。其实在更一般的情况下,这类计算结果是通过后台接口进行返回,这也是就我们最常用的异步回调的方式,但是如果仅仅使用前端进行实现,那么我们就有必要再开启一个新的线程为我们进行计算(模拟后端接口)。如果我们依旧使用主线程进行计算,那么很有可能会产生页面卡顿的情况,特别是在计算时间过久的情况下,会给用户带来非常差的使用体验。

结语

这篇博客主要简要的讲述了Worker的使用方式并且给出一个demo让大家更直观的进行理解。对于一些前端需要使用多线程的场景,我们都可以使用Worker进行解决(比如面试题:实现setTimeout)。同样,如果大家有任何疑问,欢迎评论区留言或者私信我,如果本篇文章有讲述不对之处也欢迎评论区指正,下期再会。

前端多线程上传minio可以通过Web Worker实现。Web Worker是一种在后台运行的JavaScript脚本,可以在不阻塞主线程的情况下进行耗时操作,如文件上传。以下是一个基本的前端多线程上传minio的示例代码: 1. 首先创建一个Worker对象,指定worker.js作为后台脚本: ```javascript var worker = new Worker("worker.js"); ``` 2. 在worker.js中编写上传代码,使用XMLHttpRequest或Fetch API上传文件。根据需求,可以将文件分割成多个小片并上传,或者使用断点上传技术实现断点续传。上传完成后,使用postMessage()方法将上传结果发送回主线程: ```javascript self.addEventListener('message', function(e) { var file = e.data.file; var xhr = new XMLHttpRequest(); xhr.open('PUT', 'http://minio.example.com/' + file.name, true); xhr.setRequestHeader('Content-Type', file.type); xhr.setRequestHeader('Content-Length', file.size); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200 || xhr.status === 201) { self.postMessage({success: true, message: '上传成功'}); } else { self.postMessage({success: false, message: '上传失败'}); } } }; xhr.upload.onprogress = function(event) { var percent = Math.round((event.loaded / event.total) * 100); self.postMessage({progress: percent}); }; xhr.send(file); }, false); ``` 3. 在主线程中监听worker的message事件,接收上传结果并更新UI: ```javascript worker.addEventListener('message', function(e) { if (e.data.success) { alert('上传成功'); } else { alert('上传失败'); } }); ``` 4. 调用worker.postMessage()方法向worker发送上传任务: ```javascript var file = document.querySelector('#fileInput').files[0]; worker.postMessage({file: file}); ``` 需要注意的是,Web Worker只能在支持HTML5的浏览器中使用,且存在一定的安全性限制。上传到minio需要使用PUT请求,并设置正确的Content-Type和Content-Length头信息,否则上传会失败。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值