Starting to work with web workers.

This commit is contained in:
Eric van der Vlist 2022-11-06 17:53:01 +01:00
parent 4b53b9d4ba
commit 9089b08c6e
4 changed files with 107 additions and 0 deletions

View File

@ -0,0 +1,28 @@
import dispatch, { init, worker } from './dispatcher-main';
describe('The dispatcher-main', () => {
var postMessage = jest.fn();
beforeEach(() => {
global.SharedWorker = jest.fn(function (source) {
this.source = source;
this.port = {
postMessage,
};
return this;
});
init();
});
test('should create a new shared web worker', () => {
expect(SharedWorker).toBeCalled();
});
test('should create a onmessage function', () => {
expect(worker.port.onmessage).toBeDefined();
});
test('should return a promise if no callback is provided', () => {
expect(dispatch('ping')).toBeInstanceOf(Promise);
});
test('should send back the message', () => {
dispatch('ping');
expect(postMessage).toBeCalledWith({ id: 0, payload: 'ping' });
});
});

View File

@ -0,0 +1,47 @@
declare global {
var dispatcherQueue: { index: number; queue: Map<number, any> };
}
export var worker: any;
export const init = () => {
globalThis.dispatcherQueue = { index: 0, queue: new Map() };
worker = new SharedWorker('./dispatcher-worker');
worker.port.onmessage = (event: any) => {
const { id, payload } = event.data;
dispatcherQueue.queue.get(id)(null, payload);
dispatcherQueue.queue.delete(id);
};
};
const dispatch = (
payload: any,
callBack?: (error: any, result: any) => void
) => {
if (worker === undefined) {
init();
}
if (callBack === undefined) {
/** If a callback function is not provided, return a promise */
return new Promise((resolve, reject) => {
dispatch(payload, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
}
/** Otherwise, use the callback function */
dispatcherQueue.queue.set(dispatcherQueue.index, callBack);
const message = {
id: dispatcherQueue.index++,
payload: payload,
};
worker.port.postMessage(message);
};
export default dispatch;

View File

@ -0,0 +1,19 @@
import worker from './dispatcher-worker';
describe('The dispatcher-worker ', () => {
let port;
beforeEach(() => {
port = {
postMessage: jest.fn(),
};
worker.onconnect({ ports: [port] });
});
test('creates a onmessage function', () => {
expect(port.onmessage).toBeDefined();
expect(port.postMessage).not.toBeCalled();
});
test('receives a ping and sends a pong', () => {
port.onmessage({ data: { id: 5, payload: 'ping' } });
expect(port.postMessage).toBeCalledWith({ id: 5, payload: '"ping" pong' });
});
});

View File

@ -0,0 +1,13 @@
const self = globalThis as unknown as SharedWorkerGlobalScope;
self.onconnect = function (e) {
var port = e.ports[0];
port.onmessage = function (e) {
console.log(`Worker received ${JSON.stringify(e)}`);
const { id, payload } = e.data;
port.postMessage({ id: id, payload: `${JSON.stringify(payload)} pong` });
};
};
export default self;