js中调用worker工程化结构

仿照gaia-gzip的结构进行分析:

---gzip
 |---gzip.js          # gzip主线程引入部分
 |---gzip_worker.js   # worker工作者线程
 |---gzip.min.js      # gzip的js版本库

内容:

gzip.js

/* exported Gzip */
'use strict';

var Gzip = {
  // worker的绝对路径
  WORKER_URL: '/shared/js/gzip/gzip_worker.js',
  // Gzip仅向外提供一个compress执行函数
  compress: function(payload) {
    return new Promise((resolve, reject) => {
      var worker = new Worker(this.WORKER_URL);
      // 加载失败延时报错保护,会主动终止worker
      // Protect against the worker failing for whatever reason.
      var workerTimeout = setTimeout(function() {
        worker.terminate();
        reject('Failed to compress: gzip worker did not respond.');
      }, 10000);
      // 通信监听 -- 收到消息->清除延时,终止线程->向外抛出数据/没有结果向外抛错
      worker.onmessage = function(msg) {
        clearTimeout(workerTimeout);
        worker.terminate();

        var data = msg.data;
        if (data.returnResult) {
          resolve(data.gzipData);
        }
        else {
          reject('Failed to compress: ' + data.error);
        }
      };
      // 向worker通信,传递两个参:cmd执行命令,payload工作任务开销
      worker.postMessage({
        cmd: 'gzip',
        payload: payload
      });
    });
  }
};

gzip_worker.js

/* global Zlib */
'use strict';
// 外部库在worker中进行引入
importScripts('gzip.min.js');
// 只有一个通信监听
self.onmessage = function(message) {
  // 取工作指令
  var cmd = message.data.cmd;

  if (cmd === 'gzip') {
    // 将传进来的开销任务字符串转为Uint8Array格式,供gzip使用
    // gzip function requires Uint8Array
    var textEncoder = new TextEncoder('utf8');
    var payload = message.data.payload;
    var uint8Data = textEncoder.encode(payload);

    try {
      var gzip = new Zlib.Gzip(uint8Data);
      var compressed = gzip.compress();
      // 任务执行成功与否用returnResult进行指示,并返回不同的包裹内容
      postMessage({returnResult: true, gzipData: compressed});
    }
    catch(e) {
      postMessage({returnResult: false, error: e});
    }
  } else {
    console.warn('GzipWorker, unsupported cmd:', cmd);
  }
};

结构抽象

/******************************mainjs********************************/
/* 暴露包名 */
'use strict';
var 包名 = {
  WORKER_URL: worker地址,
  执行任务: function(payload) {
    return new Promise((resolve, reject) => {
      var worker = new Worker(this.WORKER_URL);
      // 加载失败延时报错保护,会主动终止worker
      var workerTimeout = setTimeout(function() {
        worker.terminate();
        reject(执行任务失败原因);
      }, 10000);
      // 通信监听 -- 收到消息->清除延时,终止线程->向外抛出数据/没有结果向外抛错
      worker.onmessage = function(msg) {
        clearTimeout(workerTimeout);
        worker.terminate();

        var data = msg.data;
        // 自定义data内数据结构
        if (data.returnResult) {
          resolve(data.gzipData);
        }
        else {
          reject(执行任务失败 + data.error);
        }
      };
      // 向worker通信,传递两个参:cmd执行命令,payload工作任务开销
      worker.postMessage({
        cmd: 执行命令,
        payload: payload
      });
    });
  }
};
/*****************************workerjs*******************************/
/* 声明依赖库 */
'use strict';
// 外部库在worker中进行引入
importScripts(库地址);
// 只有一个通信监听
self.onmessage = function(message) {
  // 取工作指令
  var cmd = message.data.cmd;

  if (cmd === 工作指令) {
    try {
      var 库调用结果 = 库调用指令(message.data.payload);
      // 任务执行成功与否用returnResult进行指示,并返回不同的包裹内容
      postMessage({returnResult: true, xxxData: 库调用结果});
    }
    catch(e) {
      postMessage({returnResult: false, error: e});
    }
  } else {
    console.warn(不支持命令警告);
  }
};
原文地址:https://www.cnblogs.com/hencins/p/13912842.html