HTML5与移动Web:多线程

WebWork的作用

       为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。

Web Worker 有以下几个使用注意点

1)同源限制

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

2DOM 限制

Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但是,Worker 线程可以navigator对象和location对象。

3)通信联系

Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。

4)脚本限制

Worker 线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。

5)文件限制

Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。

主线程

创建Work线程

      主线程采用new命令,调用Worker()构造函数,新建一个 Worker 线程。

var myWorker = new Worker(jsUrl, options);

var myWorker = new Worker('worker.js', { name : 'myWorker' });

Worker()构造函数,可以接受两个参数。第一个参数是脚本的网址(必须遵守同源政策),该参数是必需的,且只能加载 JS 脚本,否则会报错。第二个参数是配置对象,该对象可选。它的一个作用就是指定 Worker 的名称,用来区分多个 Worker 线程。

主线程向Work线程发送消息

worker.postMessage('Hello World');

worker.postMessage({method: 'echo', args: ['Work']});

worker.postMessage()方法的参数,就是主线程传给 Worker 的数据。它可以是各种数据类型,包括二进制数据。

主线程接收Work线程发回来的消息

worker.onmessage = function (event) {

  console.log('Received message ' + event.data);

  doSomething();

}

主线程关闭Work线程

worker.terminate();主线程主动关闭Worker线程。

self.close();用于在 Worker 内部关闭自身。

Work线程

Worker 线程内部需要有一个监听函数,监听message事件。

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

self代表子线程自身,即子线程的全局对象。因此,等同于下面两种写法。

// 写法一
this.addEventListener('message', function (e) {
  this.postMessage('You said: ' + e.data);
}, false);
// 写法二
addEventListener('message', function (e) {
  postMessage('You said: ' + e.data);
}, false);

Worker 线程可以调用不同的方法

self.addEventListener('message', function (e) {
  var data = e.data;
  switch (data.cmd) {
    case 'start':
      self.postMessage('WORKER STARTED: ' + data.msg);
      break;
    case 'stop':
      self.postMessage('WORKER STOPPED: ' + data.msg);
      self.close(); // Terminates the worker.
      break;
    default:
      self.postMessage('Unknown command: ' + data.msg);
  };
}, false);

Worker 加载脚本

Worker 内部如果要加载其他脚本,有一个专门的方法importScripts()。

importScripts('script1.js');

该方法可以同时加载多个脚本。

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

共享线程

创建共享Worker需要SharedWorker构造函数:

var worker = new SharedWorker('shared-worker.js');

  • 共享Worker的实例由URL唯一确定,还可以传递一个可选的name参数给SharedWorker,为Worker实例显式指定一个名字,该名字可以为同一个js文件创建多个Worker实例:
  • 共享Worker的边界同样受制于同源策略,不同的站点可以使用同样的name。如果同一个站点想为不同的js使用同样的worker name就会报错。

worker.port.postMessage(txt.value);

  •     work.port是MessagePort对象
  •     MessagePort接口代表MessageChannel的两个端口之一,允许从一个端口发送消息并监听它们到达另一个端口。
  •     接口的port属性SharedWorker返回MessagePort用于通信和控制共享工作程序的对象。

先监听事件onconnect,不是onmessage事件!这个适用于监听链接事件的,当你有web开始链接这个共享进程,这个事件就会被调用

可以通过事件的ports参数引用连接端口; 此引用可以onmessage附加一个处理程序来处理通过端口传入的消息,其postMessage()方法可用于使用worker将消息发送回主线程。

发布了349 篇原创文章 · 获赞 161 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/qq_42192693/article/details/103865363
今日推荐