web worker

web Worker

web Worker 文件单独写在一个文件中,在main worker 中 执行的文件里使用下面语句启用 web Worker。 如果引用的文件是存在的,则会异步下载,下载完成后,web worker才会开始。如果资源文件加载失败(404),worker 回静默失败(fail sliently)。

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

创建worker 成功后,使用 worker.postMessage() 来启用它。

使用 Message Passing 与 worker 通信

worker 与上层页面(Parent Page)通信基于事件系统和 postMessage方法。该方法接收字符或者JSON对象作为唯一的参数,最近新一代的现代浏览器支持传入JSON对象。需要注意的是JSON对象是被复制传递的,worker 和 parent Page 操作的不是一个实例,可以理解为在接收数据时经历了编码和解码。这个特性同样适用于支持文件,二进制,ArrayBuffer等类型的浏览器。因此当使用postMessage传递较大文件的时候需要注意这个问题。为了解决这个问题可以使用transferObject[Transferring is effectively recreating the object while sharing a reference to the underlying data and then detaching the object being transferred.]它用于传递重型资源的使用权,并不是所有的对象都是适用于使用它。理解为他是引用传递,没有复制的过程,不同与引用传递的是一旦传递了该数据,那么原有的数据会被清空不可以再继续被使用,他的内容被传递到worker的上下文环境中。

main script:

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

worker.addEventListener('message', function(e) {
  console.log('Worker said: ', e.data);
}, false);

worker.postMessage('Hello World'); // Send data to our worker.

worker :

self.addEventListener('message', function(e) {
  self.postMessage(e.data);
}, false);

woker 可用功能

可以的:

  • navigator 对象
  • location (只读)
  • XMLHTTPRequest
  • setTimeout()/clearTimeout() and setInterval()/clearInterval()
  • Application Cache
  • 使用importScripts() 方法加载外部脚本
  • Spawning other web workers

不可以的:

  • 操作DOM
  • window对象
  • document 对象
  • parent 对象

使用 importScripts

importScripts('script1.js');
importScripts('script2.js');

// or

importScripts('script1.js', 'script2.js');

subWorker

webWorker可以spawn subWorker。这有利于在运行时进一步分解大任务。

警告caveart:

  • subWorker 必须与 parent Page 同源
  • subWorker 的 URIs 是被解析为相对于 Parent Workers 资源的。
  • 由于 worker 之间的通信使用的 copied 方式,使用subWorker时需要注意系统资源的开销。

inline worker

再执行过程中创建一个worker, 或者创建内建页面而不是独立的woker文件。使用 Blob 可以在 main logic 通过创建一个 URL 处理 woker code 。

var blob = new Blob([
    "onmessage = function(e) { postMessage('msg from worker'); }"]);

// Obtain a blob URL reference to our worker 'file'.
var blobURL = window.URL.createObjectURL(blob);

var worker = new Worker(blobURL);
worker.onmessage = function(e) {
  // e.data == 'msg from worker'
};
worker.postMessage(); // Start the worker.

这个巧妙的使用了 window.URL.createObjectURL(),这方法创建了一个可以引用Dom
File or Blob 对象的简单的url 字符串。Blob URL 是唯一的并且持续应用的这个生命周期直到document unload。使用 window.URL.revokeObjectURL 来回收创建的Blob URL()。

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8" />
</head>
<body>

 <div id="log"></div>

 <script id="worker1" type="javascript/worker">
   // This script won't be parsed by JS engines
   // because its type is javascript/worker.
   self.onmessage = function(e) {
     self.postMessage('msg from worker');
   };
   // Rest of your worker code goes here.
 </script>

 <script>
   function log(msg) {
     // Use a fragment: browser will only render/reflow once.
     var fragment = document.createDocumentFragment();
     fragment.appendChild(document.createTextNode(msg));
     fragment.appendChild(document.createElement('br'));

     document.querySelector("#log").appendChild(fragment);
   }

   var blob = new Blob([document.querySelector('#worker1').textContent]);

   var worker = new Worker(window.URL.createObjectURL(blob));
   worker.onmessage = function(e) {
     log("Received: " + e.data);
   }
   worker.postMessage(); // Start the worker.
 </script>
</body>
</html>

这种方式引用外部脚本时,需要使用绝对路径方式来引用,或者在postMessage里传入url,手动解析域名拼合出访问的路径。

错误监听和处理

错误对象的结构:

{
filename:// 文件
lineno:// 错误行数
message:// 错误信息
}
 function onError(e) {
    document.getElementById('error').textContent = [
      'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message
    ].join('');
  }

  function onMsg(e) {
    document.getElementById('result').textContent = e.data;
  }

  var worker = new Worker('workerWithError.js');
  worker.addEventListener('message', onMsg, false);
  worker.addEventListener('error', onError, false);
  worker.postMessage(); // Start worker without a message.

试用场景

  • 预加载缓存数据
  • 代码高亮或者实时文本格式化
  • 拼写检查
  • 解析视频或音频数据
  • background I/O 或者 webservices 轮询
  • 处理大量数组或者JSON响应
  • canvas中的图片过滤
  • 更新本地数据库多条记录

web Worker

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容