乐趣区

关于javascript:Web-Worker靓仔要不要试试开个子线程耍耍很快的哦

前言

大家好,我是林三心,用最通俗易懂的话讲最难的知识点 是我的座右铭,根底是进阶的前提 是我的初心,明天给大家讲一个你们既相熟又生疏的货色——Web Worker

为什么 js 是单线程语言?

先给大家说说 JavaScript 为啥是一个单线程语言呢?咱们都晓得,JavaScript 是一门以前端为主的语言,而前端的舞台就是浏览器,而浏览器通过什么取悦用户呢?通过的是一个一个的 DOM 节点组成的页面。所以说,JavaScript 最终的目标都要以页面展示的品质为目标。

而 JavaScript 设计为单线程语言也是为了页面,咱们假如 JavaScript 是多线程语言,如果有一天,线程 1 在批改 DOM 节点,同时线程 2 也在批改同一个 DOM 节点,那请问页面应该听谁的?这就会造成抵触,而这在用户背后可是不被容许的,所以 JavaScript 设计成了单线程语言,想要操作啥,都得按着程序来。

Web Worker?

背景

刚刚也说了 JavaScript 是单线程语言,这也造成了许多问题。不晓得大家平时开发的时候,有没有遇到这样的事:解决一个超级大的数据,导致整个代码的逻辑被阻塞了一段时间

说说我遇到的场景吧:

  • 1、大文件切片上传配 hash 时,需解决一小段时间
  • 2、树形数据前端解决时,须要解决一小段时间
    而这可能导致了什么 假死 问题呢?
  • 1、页面渲染的阻塞
  • 2、前面代码执行的阻塞

是什么?

Web Worker 为了解决浏览器 假死 这个问题而孕育而生的一项新技术。它是多线程模型,也是基于宿主。它属于 JavaScript 线程中的一个子线程,它齐全受主线程管制,然而在 Web Worker 外面是不能操作 DOM 的。须要保障 DOM 的唯一性,因而主的基调不能扭转,然而须要有一个新的线程来分担繁冗的计算工作,这个也就是 Web Worker

兼容性:

Web Worker 有以下特点:

  • 1、一旦新建,则不会被主线程打断。即使是主线程卡死,Web Worker 依然运行中
  • 2、Web Worker 也受同源策略限度,同源网页能力拜访
  • 3、不能操作和拜访 DOM,后面也说了多线程操作 DOM 容易造成抵触,所以禁止
  • 4、不能应用全局交互办法(alert、confirm 等),其余全局办法根本能够应用
  • 5、不能读取本地文件(其实浏览器自身就禁止 JavaScript 读取本地文件,出于平安思考)
  • 6、worker 线程与主线程不共享作用域与资源
  • 7、Web Worker 有两种:

    • Dedicated Web Worker :专用线程,只能在一个网页里应用这个线程
    • Shared Web Worker :共享线程,能够在多个同源的网页中共享,也是跨页面通信的伎俩之一

应用 Web Worker

场景

为了让大家看到 Web Worker 的成果,我新建了几个文件

// index.html
<script src="./index.js"></script>
<img src="./ 头像.jpg" alt="">
// index.js

console.time('解决数据工夫')

// 模仿数据处理
function handleData(num) {for (let i = 0; i < num; i++) {
    let str = ''
    while (str.length < 150) {str += '哈'}
  }
}

handleData(2000000)
console.timeEnd('解决数据工夫')

咱们能够看看解决数据花了多少工夫:

而图片的渲染也是在这个工夫之后(渲染图片也须要肯定工夫,所以有差值),这也阐明了刚刚的数据处理,阻塞了页面的渲染:

Web Worker 根本应用

我的项目开发中用 Dedicated Web Worker ,比拟多,所以讲讲这个的根本应用吧

改写一下 index.js 中的代码

// index.js

// 实例一个 Woeker,并传入指标文件门路,这个指标文件将会生成一个 worker 线程
const worker = new Worker("data.js")
// 应用 postMessage 传输信息到指标文件
worker.postMessage(2000000)
// 应用 onmessage 承受信息
worker.onmessage = (e) => {console.log(e.data)
};
// 应用 onerror 进行指标文件,也就是指定 worker 线程产生谬误时的回调
worker.onerror = function (e) {console.log("error at" + e.filename + ":" + e.lineno + e.message)
};

而后咱们创立一下指标文件 data.js ,他将会生成一个 worker 线程

// 应用 importScripts 进行文件的援用,可援用 url、本地 js 文件
importScripts('xxxxxxx')
// importScripts('xxxxxxx', 'xxxxxxxx') 也能够传多个

// 模仿数据处理
function handleData(num) {for (let i = 0; i < num; i++) {
    let str = ''
    while (str.length < 150) {str += '哈'}
  }
}

onmessage = async (e) => {console.time('解决数据工夫')
  const res = handleData(e.data)
  postMessage('解决完了')
  console.timeEnd('解决数据工夫')
}

成果

咱们再来看看代码和渲染的成果,跟方才一开始的比照下:

图片渲染也没有被阻塞:

勾销过程

能够应用 terminate 办法完结过程

worker.onmessage = (e) => {
  // 报错时马上终止指定 worker 过程
  worker.terminate()
  console.log(e.data)
}

集体了解

其实 Web Worker 实质上并没有扭转 JavaScript 单线程 这一事实,它借助的是 浏览器的多线程

结语

我是林三心,一个热心的前端菜鸟程序员。如果你上进,喜爱前端,想学习前端,那咱们能够交朋友,一起摸鱼哈哈,摸鱼群,加我请备注【思否】

退出移动版