Skip to content

Instantly share code, notes, and snippets.

@hijiangtao
Created March 17, 2019 08:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hijiangtao/22607ea9e5f4dfe504381a99d4134142 to your computer and use it in GitHub Desktop.
Save hijiangtao/22607ea9e5f4dfe504381a99d4134142 to your computer and use it in GitHub Desktop.
Dynamic Web Worker Demo
const BASE_DATASETS = {
airports: {
PKU: { lat: 1, lng: 1, key: 'OKU', count: 1 },
// ...
}
}
export default BASE_DATASETS;
/**
* DynamicWorker Demo
*/
import BASE_DATASETS from './data';
/**
* 数据转换计算方法
*/
const formatRawData = (data) => {
console.time('Worker Internal Calculation');
// base data
const {airports} = base;
const {records = []} = data;
const res = [];
records.forEach((e) => {
if (airports.indexOf(e.column) !== -1) {
res.push([
// ...
]);
}
})
console.timeEnd('Worker Internal Calculation');
return res;
}
/**
* DynamicWorker class
*/
class DynamicWorker {
constructor(worker = formatRawData) {
// 依赖的全局变量声明,如果 BASE_DATASETS 非字符串形式,可调用 JSON.stringify 等方法进行处理,保证变量的正常声明
const CONSTS = `const base = ${BASE_DATASETS};`;
// 转换计算方法声明
const formatFn = `const formatFn = ${worker.toString()};`;
/**
* 内部 onmessage 处理
*/
const onMessageHandlerFn = `self.onmessage = ({ data: { data, flag, coverage } }) => {
console.log('Message received from main script');
const {method} = data;
if (data.data && method === 'format') {
self.postMessage({
data: formatFn(data.data),
flag
});
}
console.log('Posting message back to main script');
}`;
/**
* 返回结果
* @param {*} param0
*/
const handleResult = ({ data: { data, flag } }) => {
const resolve = this.flagMapping[flag];
if (resolve) {
resolve(data);
delete this.flagMapping[flag];
}
}
const blob = new Blob([`(()=>{${CONSTS}${formatFn}${onMessageHandlerFn}})()`]);
this.worker = new Worker(URL.createObjectURL(blob));
this.worker.addEventListener('message', handleResult);
this.flagMapping = {};
URL.revokeObjectURL(blob);
}
/**
* 动态调用
*/
send(data) {
const w = this.worker;
const flag = new Date().toString();
w.postMessage({
data,
flag,
});
return new Promise((res) => {
this.flagMapping[flag] = res;
})
}
close() {
this.worker.terminate();
}
}
export default DynamicWorker;
import DataWorker from './dynamicWorker.js';
const worker = new DataWorker();
const result = []; // demo 数据
worker.send({
method: 'format',
data: result
}).then((data) => {
// 处理结果
})
@liujun3660105
Copy link

是否可以通过在DymanicWorker这个类文件中,通过import已经安装的其他模块 在worker中的复杂逻辑处理中调用引入

@hijiangtao
Copy link
Author

你可以指定 worker 的入口引用是你自定义编译后的产物,这样就可以按照标准的 ES Modules 写法来写了,打包工具可以是 webpacjk,要简单的话可以试试 rollup

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment