web worker 实践

1.web worker

  在浏览器中JavaScript主线程与UI渲染线程是互斥的。即UI渲染线程会阻塞JavaScript线程的运行。

  web worker允许创建工作线程,并可以与JavaScript主线程同时运行,可以让一些占用大量计算资源的计算在worker线程上运行。

  worker线程的出现是为了,大量的计算占用javascript 主线程,导致 DOM操作阻塞。worker  线程一旦新建成功,就会一直运行,有利于随时响应主线程的通信,但这也会造成worker 线程比较消耗资源,所以在使用完成时,应该立即结束 worker 线程。

  出于安全和性能的考虑,worker 线程的运行有一下限制:

   (1)同源限制

    分配给worker线程,运行的脚本文件,必须与主线程脚本文件同源。

  (2)DOM 操作限制

    worker 的执行上下文是一个最小化的运行环境,没有 DOM,window ,parent 等全局对象,只有最小化的 navigator,和只读的 location对象。

  (3)通信联系

    由于worker 与主线程的执行上下文不同,所以worker 线程与主线程之间的通信,只能通过 postMessage 来完成。

  (4)脚本限制

    worker线程不能执行 alter(),confirm(),方法,但是可以使用 XMLHttpRequert 对象发出 Ajax 请求。

  (5)文件限制

    worker 线程无法读取本地文件,它所加载的脚本必须来自网络,即不能打开本地文件系统(file://)。<1>由于 worker 需要一个 js文件来创建线程,而es6 中的模块无法直接引入一个js文件,所以在现在的 单页面应用中需要创建 worker 线程需要,引入 worker-loader 插件。worker-loader 加载js文件 来创建 worker。<2>由于worke线程中使用的文件必须来自网络,所以在 worker 线程中引入脚本或者库,需要 通过 importSript()来加载对应的脚本或者库。但是 webpack 打包后的应用模块,成为了一个个 chunk ,是无法通过对应的路径加载到对应的模块的,这时在应用来我worker-loader 的情况下,可以通过 require()或者 import 来加载对应的库,而不是通过 importScript().

  javaScript 允许主线程把二进制直接转移给子线程,但是一旦转移,主线程就无法使用这些二进制数据,这是为了防止不同线程同时修改数据会造成数据不一致性问题。

  

 1 //主线程与worker线程之间的通信
 2 //worker 可以利用XMLHttpRequest加载文件,
 3 
 4 var worker = new worker('js/worker.js');
 5 worker.postMessage(args);
 6 worker.onmessage = function(event){
 7      document.getElementById('result').textContent = event.data;};
  worker.terminate() // 结束 worker线程
8 9 //workerjs 10 onmessage = function(e){ 11 var calcuResult = e.data; 12 for(var i=0;i<1000;i++) 13 calcuResult+=i; 14 } 15 postMessage(calcuResult);

 

原文地址:https://www.cnblogs.com/wust-hy/p/7484974.html