一、引
最近打算弄点面试778,所以开始系统的学习下js的一些知识,把一些还没好好认真看看的知识,都梳理一下吧,有幸能看到这篇文章的问,希望你也可以学的更好,我只是在前端路上一路埋头走下去不准备回头的小菜鸟,让我们开始吧
二、介绍
知道JS的都知道,JS是由于历史的原因导致它是单线程的语言,但是在越来越多的开发中发现,多线程也是有必要的,所以在HTML5的规范中,把多线程的解决方案Web Worker
写了进来。具体的讲下Web Worker
的作用,就是为 JS 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给子线程进行后台运行。而主线程在前端运行,两者互不干扰。等到 worker
线程完成计算任务,再把结果 post
给主线程。这样就会有很多好处,比如一些高I/O,或者计算密集型或者高延迟的任务都可以后台运行,而不影响前端UI的运行,各司其职,提高用户的体验
当然在 worker
有这么多好处的同时,也是有一点点的坏处的,上面说了创建的子线程是后台运行的,所以它和主线程是互不影响的,所以对子线程worker的操作只有对其通信,当子线程一创建即会运行,创建了多了也会影响资源的使用,所以当任务结束后,应该手动关闭子线程。
三、限制
它这么好,也是有点限制的。
- 同源问题,对于处理的脚本都要遵循是同源文件下的脚本。
- 子线程是和主线程相互独立的,所以是无法读取主线程上的
DOM
信息,wondows
,document
等对象的,但是 子线程也是有它特有的对象的。 - 子线程和主线程不可直接调用,通过
postMessage
,onMessage
方法来交互互相的数据 - 子线程无法读取本地文件,只可以请求到网络上的文件。
四、示例
1、主线程内:
1.1.创建
let worker = new Worker('www.wxample.com/worker.js',options)
//这是第一种,直接读取另一个文件的worker脚本,options 是一个对象,附属于worker对象,比如可以options={name: 'new_worker'},在worker内部执行 self.name 会得到 new_worker
let my_worker = `
function(){
......
}
`
let blob = new Blob([my_worker]);
let worker = new Worker(window.URL.createObjectURL(blob));
//这是第二种,是通过blob读取本文件中的一段信息,然后通过内置的API去创建一个 worker
1.2.消息
//上面我们已经创建了一个 worker 线程,所以主线程向 worker线程 发送消息只需要:
worker.postMessage('hello main Worker')
//主线程可以通过API 接受worker线程发送过来的信息
worker.onmessage = e =>{
console.log('message:' + e.data)
}
1.3.关闭
worker.terminate();
//这样 一个发送、接收、关闭的任务就完成了。
2. 子线程内
2.1 接收信息
self.addEventListener('message', (e) =>{
self.postMessage('message: ' + e.data);
}, false);
// self 可写可不写,因为 self是代表的 worker线程的本身。
2.2 发送消息
self.postMessage('message : im worker');
2.3 关闭
worker.close();
// 在worker内部, 这样即可关闭本身了
2.4 importScripts()
importScripts('www.example.com/other1.js', ......);
Worker 线程有个内置函数 imprtScripts()
来引入脚本,该函数接受0个或者多个URI作为参数。浏览器加载并运行每一个列出的脚本,每个脚本中的全局对象都能够被 worker 使用。如果脚本无法加载,将抛出异常,接下来的代码也无法执行。而之前执行的代码依然能够运行。importScripts()
之后的函数声明依然会被保留,因为它们始终会在其他代码之前运行。由于脚本的下载顺序不固定,但执行时会按照传入 importScripts()
中的文件名顺序进行。这个过程是同步完成的;直到所有脚本都下载并运行完毕,importScripts()
才会返回。
五、实例
//把上传图片的任务交给子线程去执行
// main.js
let worker = new Worker('www.wxample.com/uploadImage.js',{
image_name: 'image',
image_url: 'file://d:........jpg'
});
worker.onmessage = function (e) {
console.log(e.data)
};
//worker.js
function uplaod(name, url ,callback){
.....
}
upload(self.image_name, self.image_url, ()=>{
self.postMessage('upload OK!')
})
//上传的时候也可以新建几个新的worker,分片上传,自己发挥了!
六、总结
对于单线程的js来说, web Worker的诞生让js更加的强大,可以更加得心应手的处理 大数据运算,高延迟应用,高堵塞的事件等,让处理的方法更多,也让前端的使用体验更好
来源:CSDN
作者:nysheng
链接:https://blog.csdn.net/qq_32867271/article/details/104724350