async-thread-worker
async-thread-worker copied to clipboard
An async/await abstraction for Web Workers (and `node:worker_threads`)
async-thread-worker
An async/await
abstraction for Web Workers
About
async-thread-worker
presents an abstraction of Web Worker thread communication based on the client-server model. Supported features are:
-
await
ing thread operations, - integration of basic Web Worker APIs (e.g. transferables, the
terminate()
method etc.), and - class methods/interfaces for implementing client-server style functionality.
After introducing some basic examples for quickly getting started, we demonstrate applications using Wasm binaries (C code compiled by Emscripten and Rust code by wasm-pack
) embedded inside worker threads.
For other libraries that realize similar functionality, you might also consider:
Getting Started
Installation
$ npm install async-thread-worker
Usage
Here's a basic example of implementing a worker (abstracted as thread
) and interacting with it.
Use sendRequest()
and sendResponse()
for client-server style communications.
[ demo | source ]
index.html: Synchronously sending requests to a worker.
// <script src='async-thread-worker.min.js'></script>
const thread = new AsyncThreadWorker.Thread('my-thread-worker.js');
for (let payload of ['a', 'b', 'c', 'd']) {
const response = await thread.sendRequest(payload);
console.log('[main] got response:', response);
}
my-thread-worker.js: Implementation of the worker. Use the provided id
to respond to a request.
importScripts('async-thread-worker.min.js');
class MyThreadWorker extends AsyncThreadWorker.ThreadWorker {
onRequest(id, payload) { // impl
console.log('[worker] got request with:', payload);
this.sendResponse(id, payload.toUpperCase());
}
}
const myThreadWorker = new MyThreadWorker(self);
The results in the developer console:
[worker] got request: a
[main] got response: A
[worker] got request: b
[main] got response: B
[worker] got request: c
[main] got response: C
[worker] got request: d
[main] got response: D
Examples
- simple - Basic client-server communications with a worker. [ live | source | howto ]
-
tasks - Delegating various tasks to a worker (calculator). This example also demonstrates error handling with
try/catch
and thesendError()
API. [ live | source ] - serial-vs-parallel - Running multiple workers serially/parallelly. [ live | source ]
-
terminate -
terminate()
api example. [ live | source ] -
transferables - Transfering an
ArrayBuffer
object back and forth for efficient drawing. ThesendRequest()
andsendResponse()
APIs support transferable objects. [ live | source ] - class-sharing - Passing a JavaScript class to a worker. [ live | source ]
-
wasm-ffmpeg - webm/mp4 encoder app inspired by "Running FFMPEG with WASM in a Web Worker". In this app, we use
async-thread-worker
instead of Comlink in order to control encoder threads in more client-server oriented style. [ live | source ] - rust-fern-bench - WebVR app for benchmarking fractal computation with Rust+wasm vs JavaScript. [ live | source ] 🔗
API
AsyncThreadWorker.Thread
The Thread
class is for abstraction of the main thread's side (client).
-
constructor(path)
Creates aThread
object that is a worker's interface. The underlying Web Worker object wrapped byThread
is also created based on its implementation specified bypath
.-
path
string The path to a worker's implementation.
-
-
sendRequest(payload=undefined, transferables=[])
Sends a request to the worker (server) with datapayload
. Transferable objects can be specified in the optionaltransferbles
array so that they are efficiently sent to the other thread without structured clone. Returns a promise corresponding to the server's action (sendResponse()
orsendError()
).-
payload
object | primitive e.g.42
, or{name: 'foo', input: buf}
, wherebuf
is anArrayBuffer
. -
transferables
Array<object> e.g.[buf,]
-
-
getWorker()
Returns the raw Web Worker object wrapped byThread
(ornull
if the worker is already terminated). -
terminate()
Immediately terminates the worker (internally usingWorker.terminate()
).
AsyncThreadWorker.ThreadWorker
The ThreadWorker
class is for abstraction of the worker's side (server).
-
constructor(self, opts={})
Creates aThreadWorker
object that represents the worker thread by wrapping the bare Web Worker object (self
).-
self
DedicatedWorkerGlobalScope The Web Worker object to be wrapped. -
opts
object Optional data that can be passed toonCreate(opts)
.
-
-
onRequest(id, payload)
Called when the worker thread (server) received a request with datapayload
from the main thread (client). Implement this method to respond to the client by eithersendResponse()
orsendError()
.-
id
string An auto-generated request id to be required bysendResponse()
orsendError()
. -
payload
object | primitive
-
-
sendResponse(id, payload=undefined, transferables=[])
Sends a response to the main thread (client) with datapayload
. Transferable objects can be specified in the optionaltransferbles
array so that they are efficiently sent to the other thread without structured clone.-
id
string A request id provided byonRequest()
. -
payload
object | primitive e.g.42
, or{name: 'foo', output: buf}
, wherebuf
is anArrayBuffer
. -
transferables
Array<object> e.g.[buf,]
-
-
sendError(id, error)
Sends an error response to the main thread (client) with dataerror
.-
id
string A request id provided byonRequest()
. -
error
object | primitive
-
-
onCreate(opts)
Called when theThreadWorker
is created. One may override this method when extending theThreadWorker
class.-
opts
object Optional parameters given toconstructor()
.
-
Build
$ npm install # set up build tools
$ npm run build