Awork is a small library meant to simplify Web Workers usage in some cases.
Just wrap or decorate your function with awork
and continue using it in a usual async way:
const parsed = await awork(parseJSON)(heavyJSON)
const users = await awork(yourFetchUsersFunc)()
However, be aware of some limitations:
- Only pure functions without side effects and external dependencies can be wrapped at the moment. All necessary data should be passed to this function via arguments.
- The function should return computed value, which then will be used to fulfill the promise.
- Polyfilled features will not work correctly inside a web worker process due to external dependencies. For example, Promise polyfills will refer to variables outside the function scope, like _es6Promise (es6-promise) or _promise2 (babel-polyfill).
- If you are using awork as a decorator for a class method, remember that
this
inside the method doesn't refer to the class instance.
Via npm:
$ npm install awork --save
As a decorator:
import awork from 'awork'
class ClassWithFibonacciNumbers {
@awork()
getFibonacciNumber(num) {
let a = 1, b = 0, tmp
while (num > 0){
tmp = a
a = a + b
b = tmp
num--
}
return a
}
}
let instance = new ClassWithFibonacciNumbers()
instance.getFibonacciNumber(100)
.then((res) => console.log('100th number:', res))
.catch((err) => console.error(err))
As a wrapper:
import awork from 'awork'
function inefficientFibonacci(num) {
let a = 1, b = 0, tmp = null
while (num > 0){
tmp = a
a = a + b
b = tmp
num--
}
return b
}
let fib = awork(inefficientFibonacci)
Promise.all(
[...Array(100)].map((v, i) => fib(i))
)
.then(num => print(`First 100 Fibonacci numbers:`, num.join(', ')))
.catch(error => console.error(error))
All errors from web worker will propagate back to the main process and lead to Promise rejection:
const awork = require('awork')
function parseJSON(str) {
return JSON.parse(str)
}
awork(parseJSON)('{not even close to valid JSON}')
.then(() => console.log('Surprise'))
.catch((err) => console.log('Well, it was expected:', err))
Creating a new web worker every call is quite expensive, that's why awork keeps and reuses the same instance by default. But if you are going to call your function only once or twice - you can notify awork that there is no need to keep this web worker instance alive. To do this, pass {keepAlive: false}
to awork:
//Config decorator
@awork({keepAlive: false})
fn (args) {
// ...
}
//Config wrapper
let afn = awork(fn, {keepAlive: false})
To run examples locally, use:
- Run
yarn run build:examples && yarn run start:examples
- Open http://127.0.0.1:8080 to explore examples folder.