Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/alvarobernalg/event-worker
A simpler way of dealing with Web Workers
https://github.com/alvarobernalg/event-worker
events listener performance process promise thread threads web worker
Last synced: 22 days ago
JSON representation
A simpler way of dealing with Web Workers
- Host: GitHub
- URL: https://github.com/alvarobernalg/event-worker
- Owner: AlvaroBernalG
- License: mit
- Created: 2017-07-19T20:51:22.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2023-01-13T22:17:34.000Z (almost 2 years ago)
- Last Synced: 2024-11-24T19:20:20.954Z (about 1 month ago)
- Topics: events, listener, performance, process, promise, thread, threads, web, worker
- Language: JavaScript
- Homepage:
- Size: 1.76 MB
- Stars: 19
- Watchers: 2
- Forks: 3
- Open Issues: 29
-
Metadata Files:
- Readme: readme.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# event-worker
> Minimalistic event/promified driven web worker abstraction.[![Build Status](https://travis-ci.org/AlvaroBernalG/event-worker.svg?branch=master)](https://travis-ci.org/AlvaroBernalG/event-worker) [![npm version](https://badge.fury.io/js/event-worker.svg)](https://badge.fury.io/js/event-worker) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
## Install
### npm
```shell
npm install event-worker --save
```### CDN
https://cdn.jsdelivr.net/npm/[email protected]/index.min.js
## Usage
Basic example
In your main thread (main.js):
```js
const EventWorker = require('event-worker')const worker = new EventWorker('path/to/my/worker.js')
async function test(){
const user = await worker.emit('getUserById', { id: '30242' })/*
{
id: '30242',
name: 'neil',
lastname: 'tyson degrasse'
}
*/
//...```
And then in your web worker (worker.js) you can listen for that event and respond back with the requested data:
```js
const EventWorker = require('event-worker')const worker = new EventWorker()
worker.on('getUserById', async ({payload}) => {
let user = await getUser(payload.id)
return user // Respond back to the main thread with the data requested.
})
async function getUser(id){
let user = await fetchUserFromLocalDatabase(id)
if(user) return user
user = await fetchUserFromServer(id)
saveUserInLocaDatabase(user)
return user
}
```### Workload splitting
If you want to keep your main thread running smoothly dividing the work load of expensive computational task between multiple web workers becomes easier.
From main thread (main.js):
```js
const EventWorker = require('event-worker')const workerPath = 'path/to/my/worker.js'
const workerPool = [
new EventWorker(workerPath),
new EventWorker(workerPath),
new EventWorker(workerPath)
]const sum = (a, b) => a + b
const multiplyBy2InOtherThread = (worker, index) => worker.emit('multiply_by_2', index)
(async ()=>
(await Promise.all(
workerPool.map(multiplyBy2InOtherThread)
)).reduce(sum, 0)
)() // 6```
From worker (worker.js):
```js
importScripts('path/to/source/event-worker.js')
const worker = new EventWorker()
worker.on('multiply_by_2', ({payload}) => payload * 2 )
```
#### Bidirectional communication
You can listen for events triggered by your workers.
From main thread (main.js):
```js
//...worker.on('interestingData', ({payload})=>{
doSomethingWithInterestingData(payload)
return 'Good job worker!'
})
//..
```From worker (worker.js):
```js
//...
const res = await worker.emit('interestingData', 'interestingString')res // => 'Good job worker!!'
```
#### Inlining code
Instead of having a separate file for your worker, you can wrap your code inside a function and pass it as
an argument to the constructor of EventWorker. This is a good option when prototyping.From main (main.js):
```js
const worker = new EventWorker(async (mainThread) => {
let res = await mainThread.emit('sayingHiFromWorker', 'Hi main thread!')
console.log(res) // Hello worker!
})
worker.on('sayingHiFromWorker', ({payload}) => {
console.log(payload) // Hi main thread!
return "Hello worker!"
})
```#### Caveat
When you inline functions it is easy to get confused by the execution context. If you try to access a variable that is outside the scope of the inline function it will fail.
```js
const favoriteAnimal = 'chiguire'
const worker = new EventWorker(async (mainThread) => {
// This will get executed in a worker.
mainThread.on('onGetAnimals', ()=>{console.log(favoriteAnimal) // fails. favoriteAnimal variable is not in the same execution context.
//...
})})
```
#### Error Handling
Error handling works the same as you would expect from a promise executed in the same thread:
From main thread (main.js):
```js
const EventWorker = require('event-worker')const worker = new EventWorker('path/to/my/worker.js')
worker.emit('rejectThisCall')
.catch((reason) => {
console.log(`Rejected because: "${reason}" `)
})```
From worker (worker.js):
```js
importScripts('path/to/source/event-worker.js')
const worker = new EventWorker()
//throwing errors
worker.on('rejectThisCall', () => {
throw new Error()
})// throwing async errors
worker.on('rejectThisCallAsync', async ()=> {
throw new Error()
})```
Instead of embedding event-worker into your worker file with a module bundler, you can use the built in function `importScripts`:
```js
importScripts('path/to/source/event-worker.js')
const worker = new EventWorker()
// ...
```EventWorker reference is injected into the global scope once it's loaded.
## API
### new EventWorker(source) `EventWorker`
Creates a new instance
* source `string | function | undefined`
* If a string is passed: It will assume it is the worker source file path.
* If a function is passed it will get converted into a string an then transformed into a worker.
* If nothing (undefined) is passed it will assume that the environment is the worker.
### emit(eventName, data) `Promise`
Emits a event.
* eventName `String`
* data `Any`
### on(eventName, callback) `EventWorker`
Registers for an event.
* eventName
* callback `function(object) => Promise`
Gets executed when eventName is emited.
* object
* object.payload `any`Data sent from the event emitter to the listener.
### terminate() `void`
Immediately terminates the Worker. This does not offer the worker an opportunity to finish its operations; it is simply stopped at once.
## Changelog
### 2017-11-04
* Removed `"resolve"` and `"reject"` function properties in the `"on"` callback.## Contributing
All contributions are welcome.
## License
MIT © [Alvaro Bernal](https://github.com/AlvaroBernalG/)