JavaScript多线程-Web Worker

JS构成

ECMAScript

ECMAScript划定了JavaScript剧本的中心语法,如 数据类型、关键字、保存字、运算符、对象和语句等,它不属于任何浏览器。

Document Object Model

文档对象模子(DOM)将web页面与到剧本或编程言语连接起来。一般是指 JavaScript,但将HTMLSVGXML文档建模为对象并非JavaScript言语的一部分。DOM模子用一个逻辑树来示意一个文档,树的每一个分支的尽头都是一个节点(node),每一个节点都包含着对象(objects)。DOM的要领(methods)让你可以用特定体式格局操纵这个树,用这些要领你可以转变文档的构造、款式或许内容。节点可以关联上事宜处置惩罚器,一旦某一事宜被触发了,那些事宜处置惩罚器就会被实行。

Browser Object Model

浏览器对象模子(BOM),是用于形貌这类对象与对象之间条理关联的模子,浏览器对象模子供应了独立于内容的、可以与浏览器窗口举行互动的对象构造。BOM由多个对象构成,个中代表浏览器窗口的Window对象是BOM的顶层对象,其他对象都是该对象的子对象.

线程与历程

历程(Process)是系统资本分派和调理的单位。一个运转着的顺序就对应了一个历程。一个历程包含了运转中的顺序和顺序所运用到的内存和系统资本。假如是单核CPU的话,在统一时候内,有且只要一个历程在运转。然则,单核CPU也能完成多使命同时运转,比方你边听网易云音乐的逐日引荐歌曲,边在网易有道云笔记上写博文。这算开了两个历程(多历程),那运转的机制就是一会儿播放一下歌,一会儿相应一下你的打字,但由于CPU切换的速率很快,你基础觉得不到,以至于你以为这两个历程是在同时运转的。历程之间是资本断绝的。

那线程(Thread)是什么?线程是历程下的实行者,一个历程最少会开启一个线程(主线程),也可以开启多个线程。比方网易云音乐一边播放音频,一边显现歌词。多历程的运转实在也就是经由历程历程中的线程来实行的。一个历程下的线程是可以同享资本的,所以在多线程的情况下,须要特别注重对临界资本的接见掌握.

浏览器

现在最为盛行的浏览器为:`Chrome,IE,Safari,FireFox,Opera.

一个浏览器一般由以下几个常驻的线程:

  • 衬着引擎线程:担任页面的衬着
  • JS引擎线程:担任JS的剖析和实行
  • 定时触发器线程:处置惩罚定时事宜,比方setTimeout, setInterval
  • 事宜触发线程:处置惩罚DOM事宜
  • 异步http要求线程:处置惩罚http要求

须要注重的是,衬着线程和
JS引擎线程是不能同时举行的。衬着线程在实行使命的时刻,
JS引擎线程会被挂起。由于
JS可以操纵DOM,若在衬着中
JS处置惩罚了
DOM,浏览器可以就懵逼了。

Web Worker

简介

Web Worker (事情线程) 是 HTML5 中提出的观点,Web Workers 使得一个Web应用顺序可以在与主实行线程星散的背景线程中运转一个剧本操纵。如许做的优点是可以在一个零丁的线程中实行费时的处置惩罚使命,从而许可主(一般是UI)线程运转而不被壅塞/放慢.

Web Worker可以分为一下几类:

  • 专用线程(Dedicated Worker)

专用线程仅能被建立它的剧本所运用(一个专用线程对应一个主线程)

  • 同享线程(Shared Worker)

同享线程可以在差别的剧本中运用(一个同享线程对应多个主线程)

  • 效劳事情线程(Service Workers)

注册在指定源和途径下的事宜驱动
worker, 可以掌握关联的页面或许网站,阻拦并修正接见和资本要求,细粒度地缓存资本.

  • Chrome Workers

一种仅适用于
firefox
worker.

  • Aduio Workers

可以在收集
worker高低文中直接完成剧本化音频处置惩罚

浏览器兼容性

可以经由历程
caniuse 检察兼容性

  • Dedicated Worker 兼容性

《JavaScript多线程-Web Worker》

  • Shared Worker 兼容性

《JavaScript多线程-Web Worker》

运用场景

  • 懒加载
  • 文本剖析
  • 流媒体数据处置惩罚
  • canvas图形绘制
  • 图象处置惩罚

限定

  • 同源限定
  • 没法接见DOM
  • 有本身的高低文,没法运用Window对象
workerType高低文
Dedicated WorkerDedicatedWorkerGlobalScope
Shared WorkerSharedWorkerGlobalScope
建立线程
  • 搜检浏览器是不是支撑
if (window.Worker) {
    // some code
}
  • 专用线程
@params {String} url 示意worker将实行的剧本的URL,必需恪守同源战略
@params {Object} [options] 建立对象实例时设置的选项属性的对象
@params {Object} [options.type]
@params {Object} [options.name]
@params {Object} [options.credentials]
@returns 建立的worker
const myWorker = new Worker(url[, options]);
  • 示例
// main.js
const myDedicatedWorker = new Worker('./dedicated_worker/worker.js', { name: 'dedicatedWorker' });

// worker.js
console.log('success');
  • 同享线程
@params {String} url 示意worker将实行的剧本的URL,必需恪守同源战略
@params {Object} [options] 建立对象实例时设置的选项属性的对象
@params {Object} [options.type]
@params {Object} [options.name]
@params {Object} [options.credentials]
@returns 建立的worker
const myWorker = new SharedWorker(url[, options]);
  • 示例
// main.js
const mySharedWorker = new SharedWorker('./shared_worker/worker.js', { name: 'sharedWorker' });

// worker.js
console.log('success');
线程通讯
  • 发送信息
@params {Object} message 通报的数据对象
@params {Object} [options] 一个可选的Transferable对象的数组,用于通报所有权.假如一个对象的所有权被转移,在发送它的高低文中将变成不可用(中断),而且只要在它被发送到的worker中可用。
myWorker.postMessage(message, transferList);
  • 吸收信息
myWorker.onmessage = function(event) {
    const data = event.data; // 吸收到的音讯数据
}
  • 专用线程示例
// main.js
const myWorker = new Worker('worker.js');
myWorker.postMessage([10, 20]);
myWorker.onmessage = function (event) {
    console.log(event.data);
}

// worker.js
onmessage(event) {
    console.log(event.data);
    postMessage(event.data[1] - event.data[0]);
}
  • 同享线程示例
// main.js
const myWorker = new SharedWorker('worker.js');
myWorker.port.start();
myWorker.port.postMessage([10, 20]);
myWorker.port.onmessage = function (event) {
    console.log(event.data);
}

// worker.js
connect(event) {
    const port = event.port[0];

    port.onmessage(event) {
        port.postMessage(event.data[1] - event.data[0]);
    }
}


SharedWorker的运用中,我们发明关于
SharedWorker实例对象,我们须要经由历程
port属性来接见到重要要领;同时在
Worker剧本中,多了个全局的
connect()函数,同时在函数中也须要去猎取一个
port对象来举行启动以及操纵;这是由于,多页页面同享一个
SharedWorker线程时,在线程中须要去推断和区,分来自差别页面的信息,这是最重要的区分和缘由。

Worker线程中,selfthis都代表子线程的全局对象。关于监听 message事宜,以下的四种写法是同等的。


// 写法 1
self.addEventListener('message', function (e) {
    // ...
})

// 写法 2
this.addEventListener('message', function (e) {
    // ...
})

// 写法 3
addEventListener('message', function (e) {
    // ...
})

// 写法 4
onmessage = function (e) {
    // ...
}
  • 示例

封闭线程

myWorker.terminate(); // 主线程中运用
close(); worker线程中运用(引荐)

毛病处置惩罚

// 主线程
myWorker.onerror = function(event) {
    const lineno = event.lineno;      // 失足的剧本称号
    const filename = event.filename;  // 发作毛病的行号
    const message = event.message;    // 对毛病的形貌
} 
// 不能举行反序列化时触发
myWorker.onmessageerror = function() { ... }  // 专用线程
myWorker.port.onmessageerror function() {...} // 同享线程

外部加载剧本

供应
importScript()要领,导入一条或许以上剧本到当前
worker的作用域里.

每一个剧本中的全局对象都可以被 worker 运用.

importScript('first.js', 'second.js');

子历程

Worker可以天生子历程

  • 存在同源限定
  • Worker中的URL相干于父级Woker所在位置举行剖析

嵌入Worker

<script type="text/js-worker">
    onmessage = (event) => {
        postMessage(event.data + 1);
    }
</script>
<script>
    const workerScript = document.querySelector('script[type="text/js-worker"]');
    const blob = new Bolb(workerScript, { type: 'text/javascript' });
    const myWorker = new Worker(window.URL.createObjectURL(blob));
    myWorker.postMessage(1);
    myWorker.onmessage = (event) => {
        console.log('来自子线程音讯:', event.data);
    }
</script>

构造化克隆算法

构造化克隆算法是由
HTML5范例定义的用于复制庞杂
JavaScript对象的算法。经由历程来自
Workers
postMessage()或运用
IndexedDB存储对象时在内部运用。它经由历程递归输入对象来构建克隆,同时坚持先前接见过的援用的映照,以防止无穷遍历轮回。这一历程可以理解为,在发送方运用相似
JSON.stringfy()的要领将参数序列化,在吸收方采纳类
JSON.parse()的要领反序列化。

  • Error以及Function对象是不能被构造化克隆算法复制的;假如你尝试如许子去做,这会致使抛出DATA_CLONE_ERR的非常
  • 没法克隆DOM
  • 对象的某些特定参数也不会被保存

    • RegExp对象的lastIndex字段不会被保存
    • 属性形貌符,setters 以及 getters(以及其他相似元数据的功用)一样不会被复制。比方,假如一个对象用属性形貌符标记为 read-only,它将会被复制为 read-write,由于这是默许的情况下
    • 真相链上的属性也不会被追踪以及复制

Web Worker中可以运用的函数和类

  • 时候相干
clearInterval()
clearTimeout()
setInterval()
setTimeout
  • Worker 相干
importScripts()
close()
postMessage()
  • 存储相干
Cache
IndexedDB
  • 收集相干
Fetch
WebSocket
XMLHttpRequest

更多

    原文作者:emsoft
    原文地址: https://segmentfault.com/a/1190000018014146
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞