A small promise based wrapper over the "webworkers"
Inside
Note It uses nodejs
Note that you can't send dom objects via postMessage
Send just arraybuffer
Or inside objects
And in
Note: It's experimental feature, and api may be changed
Pool has
Note that stacktraces cannot be originaly sent from the worker to the main thread, so you're getting just string stack trace
Create a new
Send a message to the worker and return a Promise.
Send a message to the worker and return a Promise.
Add Operation.
Usage
Install:npm install webworker-promise
Inside your main bundle:// main.js
const WebworkerPromise = require('webworker-promise');
const worker = new WebworkerPromise(new Worker('worker.js'));
worker
.postMessage('ping')
.then((response) => {
// handle response
})
.catch(error => {
// handle error
});
Inside
worker.js
:// worker.js
const registerWebworker = require('webworker-promise/lib/register');
registerWebworker(async (message, emit) => {
//message - ping
return 'pong';
});
Nodejs
You can use webworker-promise with nodejs using shimNote It uses nodejs
child_process
for workersconst Worker = require('webworker-promise/lib/node-worker');
const WebWorkerPromise = require('webworker-promise');
const worker = new WebWorkerPromise(new Worker('./node-process'));
Message format
The message you send can be any object, array, string, number, etc.:// main.js
worker.postMessage({
hello: 'world'
}).then(/* ... */);
// worker.js
registerWebworker(async (message, emit) => {
console.log(message); // { hello: 'world'}
});
Note that you can't send dom objects via postMessage
Transferable
You can use transferable list for performance issueSend just arraybuffer
worker.postMessage(arrayBuffer, [arrayBuffer])
Or inside objects
worker.postMessage({myArr: arrayBuffer, myArr2: arrayBuffer2}, [arrayBuffer, arrayBuffer2]);
And in
worker.js
registerWebworker(async (message, emit) => {
return new registerWebworker.TransferableResponse(arrayBuffer, [arrayBuffer]);
});
Events
You can send events from worker to main-process// main.js
worker.postMessage('ping', [], (eventName, data) => {
eventName; // hello
data; // world
})
.then(response => {
//job end
//pong
})
// worker.js
registerWebworker(async (message, emit) => {
emit('hello', 'world');
return 'pong';
});
EventEmitter
You can use it as regular event-emitter, webworker-promise has all event-emitter methods to send events in direction worker => main or main => worker// main.js
host.on('add:ok', (sum) => {
// sum is 33;
});
worker.emit('add', 11, 22);
// worker.js
const host = registerWebworker()
.on('add', (n1, n2) => {
host.emit('add:ok', n1 + n2);
})
.once('minus', (n1, n2) => {
host.emit('minus:answer', n1 - n2);
})
// you still can add operations
.operation('foo', async () => {
return 'bar';
});
Operations
Also, you can create operations// worker.js
registerWebworker(async (message) => {
//handle postMessage
return 'pong';
})
.operation('hello', async (message, emit) => {
return 'world';
});
// main.js
worker.exec('hello')
.then(response => {
// world
})
Workers Pool
Dynamic pool for workers.Note: It's experimental feature, and api may be changed
const WorkerPool = require('webworker-promise/lib/pool');
const pool = WorkerPool.create({
src: './test.worker.js',
// or
create: () => new Worker('./test.worker.js'),
maxThreads: 3, // optional, default is 2, max numbers of workers to create if necessary
maxConcurrentPerWorker: 1 // optional, default is 1
});
pool.postMessage('hello')
.then(() => {
console.log('result');
});
Pool has
exec
and postMessage
methods with the same api as WebWorkerPromisePromises
Inside of the worker, the registered handler should return Promise or just valueError handling
Any thrown errors or rejections from the worker will be propagated to the main thread as a rejected Promise. For instance:// worker.js
registerWebworker(function (message) {
throw new Error('myException!');
});
// main.js
worker.postMessage('hi').catch(function (err) {
console.log(err.message); // 'myException!'
console.log(err.stack); // stack trace string
});
Note that stacktraces cannot be originaly sent from the worker to the main thread, so you're getting just string stack trace
Browser support
- Chrome
- Firefox
- Safari 8+
- IE 10+
- Edge
- iOS 8+
- Android 4.4+
Main bundle
new WebworkerPromise(worker)
Create a new WebworkerPromise
, using the given worker.worker
- theWorker
to use.
PromiseWorker.postMessage(message, transferableList, onEvent)
Send a message to the worker and return a Promise.message
- object - required
transferable
- transferable listonEvent
- on-event callback function to handle events from worker
- returns a Promise
PromiseWorker.exec(operationName, message, transferableList, onEvent)
Send a message to the worker and return a Promise.operationName
- string - required
message
- object
transferable
- transferable listonEvent
- on-event callback function to handle events from worker
- returns a Promise
Worker bundle
Register a message handler inside of the worker. Your handler consumes a message and returns a Promise.registerWebworker(function)
function
registerWebworker().operation(name, handler)
Add Operation.name
- string - required
handler
- handle the operation
Testing the library
First:npm install
Then to test in Node using pseudo-webworkernpm test
Or to test with coverage reports:npm run coverage
Inspired by https://github.com/nolanlawson/promise-worker