-
Notifications
You must be signed in to change notification settings - Fork 345
/
worker.ts
101 lines (87 loc) 路 2.3 KB
/
worker.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
import {window} from "./browser";
// Store blob in memory
const blob = {};
/**
* Get Object URL
* @param {Function} fn Function to be executed in worker
* @param {Array} depsFn Dependency functions to run given function(fn).
* @returns {string}
* @private
*/
function getObjectURL(fn: Function, depsFn?: Function[]): string {
const fnString = fn.toString();
const key = fnString.replace(/(function|[\s\W\n])/g, "").substring(0, 15);
if (!(key in blob)) {
// Web Worker body
blob[key] = new window.Blob([
`${depsFn?.map(String).join(";") ?? ""}
self.onmessage=function({data}) {
const result = (${fnString}).apply(null, data);
self.postMessage(result);
};`
], {
type: "text/javascript"
});
}
return window.URL.createObjectURL(blob[key]);
}
/**
* Create and run on Web Worker
* @param {boolean} useWorker Use Web Worker
* @param {Function} fn Function to be executed in worker
* @param {Function} callback Callback function to receive result from worker
* @param {Array} depsFn Dependency functions to run given function(fn).
* @returns {object}
* @example
* const worker = runWorker(function(arg) {
* // do some tasks...
* console.log("param:", A(arg));
*
* return 1234;
* }, function(data) {
* // callback after worker is done
* console.log("result:", data);
* },
* [function A(){}]
* );
*
* worker(11111);
* @private
*/
export function runWorker(
useWorker = true, fn: Function, callback: Function, depsFn?: Function[]
): Function {
let runFn;
if (window.Worker && useWorker) {
const src = getObjectURL(fn, depsFn);
const worker = new window.Worker(src);
runFn = function(...args) {
// trigger worker
worker.postMessage(args);
// listen worker
worker.onmessage = function(e) {
// release object URL from memory
window.URL.revokeObjectURL(src);
return callback(e.data);
};
// handle error
worker.onerror = function(e) {
console.error(e);
};
// return new Promise((resolve, reject) => {
// worker.onmessage = ({data}) => resolve(data);
// worker.onerror = reject;
// });
};
} else {
runFn = function(...args) {
const res = fn(...args);
callback(res);
};
}
return runFn;
}