美文网首页
工作线程-js-v1.0.0

工作线程-js-v1.0.0

作者: 一点金光 | 来源:发表于2019-07-29 16:20 被阅读0次
    ---
    title: 工作线程
    date: 2018-06-09 16:29:00
    updated: 2018-06-10 12:00:00
    categories:
    - 网页开发
    - 开发应用
    tags:
    - worker
    - nodejs
    ---
    

    #为何?

    把一些计算密集型或高延迟的任务,给 工作线程负担;这样主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。

    #限制?

    同源限制
    分配给 工作线程运行的脚本文件,必须与主线程的脚本文件同源。
    文档限制
    无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但可以navigator对象和location对象。
    通信限制
    工作线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。
    接口限制
    工作线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。
    本地限制
    无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。

    #使用?

    管理线程
    作为主线程,管理工作线程。

    // 创建管理线程
    let worker = new Worker('work.js');
    
    // 发送消息给它--工作线程
    worker.postMessage('Hello World');
    
    // 接消息来自它--工作进程
    worker.onmessage = function (event) {
      console.log('Received message ' + event.data);
    }
    
    // 监听错误处理
    worker.addEventListener('error', function (event) {
      // ...
    });
    
    // 关掉管理线程
    worker.terminate();
    

    工作线程

    // 接消息来自它--管理进程
    
    // 加载其他脚本
    importScripts('script1.js');
    
    // 关掉工作线程
    self.close();
    

    #通信?

    拷贝关系 ——适合数据较小的情况
    01.管理线程与工作线程之间的通信内容,可以是文本,也可以是对象。
    02.通过传值的方式传递,而不是传址,工作线程对通信内容的修改,不会影响到管理线程。
    03.管理线程先将通信内容串行化,然后把串行化后的字符串发给 工作线程,后者再将它还原。
    转移关系? ——适合数据较大的情况
    管理线程把二进制数据直接转移给子线程,但是一旦转移,管理线程就无法再使用这些二进制数据了。为了防止出现多个线程同时修改数据的麻烦局面使用Transferable Objects方法。

    同页面的?
    通常情况下,工作线程载入的是一个单独的 JavaScript 脚本文件,但是也可以载入与管理线程在同一个网页的代码。

    <script id="worker" type="app/worker">
          addEventListener('message', function () {
            postMessage('some message');
          }, false);
    </script>
    
    var blob = new Blob([document.querySelector('#worker').textContent]);
    var url = window.URL.createObjectURL(blob);
    var worker = new Worker(url);
    
    worker.onmessage = function (e) {
      // e.data === 'some message'
    };
    

    先将嵌入网页的脚本代码,转成一个二进制对象,然后为这个二进制对象生成 URL,再让 Worker 加载这个 URL。这样就做到了,主线程和 Worker 的代码都在同一个网页上面。

    轮询后端?
    有时,浏览器需要轮询服务器状态,以便第一时间得知状态改变。这个工作可以放在 Worker 里。

    // 创建线程
    function createWorker(f) {
      var blob = new Blob(['(' + f.toString() +')()']);
      var url = window.URL.createObjectURL(blob);
      var worker = new Worker(url);
      return worker;
    }
    var pollingWorker = createWorker(function (e) {
      var cache;
      //缓存比较
      function compare(new, old) { ... };
    
      //按时轮询
      setInterval(function () {
        fetch('/my-api-endpoint').then(function (res) {
          var data = res.json();
    
          if (!compare(data, cache)) {
            cache = data;
            self.postMessage(data);
          }
        })
      }, 1000)
    });
    
    //发送信息
    pollingWorker.onmessage = function () {
      // render data
    }
    //接受信息
    pollingWorker.postMessage('init');
    

    相关文章

      网友评论

          本文标题:工作线程-js-v1.0.0

          本文链接:https://www.haomeiwen.com/subject/cosbrctx.html