-
Notifications
You must be signed in to change notification settings - Fork 7
/
thread.ts
52 lines (42 loc) · 1.47 KB
/
thread.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
// =============================================================================
// Boost.js | Thread Class Functions
// (c) Mathigon
// =============================================================================
import {defer} from '@mathigon/core';
/**
* Converts a function into a WebWorker URL object that can be passed into
* thread(). Note that `fn` has to be a single function with no external
* references or bindings, so that it can be stringified using .toString().
*/
export function functionToWorker(fn: Function) {
const content = `onmessage = e => postMessage((${fn.toString()})(e.data))`;
const blob = new Blob([content], {type: 'application/javascript'});
return URL.createObjectURL(blob);
}
/**
* Creates a new web worker, posts it a serializable data object, and returns
* when the worker responds (or after a fixed timeout).
*/
export function thread<T = any>(url: string|URL, data: any, timeout = 5000) {
const deferred = defer<T>();
const worker = new Worker(url);
const t = setTimeout(() => {
worker.terminate();
console.error('WebWorker timeout!');
deferred.reject();
}, timeout);
worker.onmessage = (e: MessageEvent) => {
clearTimeout(t);
worker.terminate();
console.log(e);
deferred.resolve(e.data);
};
worker.onerror = (e: ErrorEvent) => {
clearTimeout(t);
console.error('WebWorker error!', e);
worker.terminate();
deferred.reject(e);
};
worker.postMessage(data);
return deferred.promise;
}