仿照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(不支持命令警告);
}
};