Skip to content

Instantly share code, notes, and snippets.

@hijiangtao
Created March 17, 2019 08:11
Show Gist options
  • Select an option

  • Save hijiangtao/22607ea9e5f4dfe504381a99d4134142 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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

@hijiangtao

Copy link
Copy Markdown
Author

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

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