All Projects → AlvaroBernalG → event-worker

AlvaroBernalG / event-worker

Licence: MIT license
A simpler way of dealing with Web Workers

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to event-worker

tgrid
TypeScript Grid Computing Framework supporting RFC (Remote Function Call)
Stars: ✭ 83 (+361.11%)
Mutual labels:  worker, thread, process
Steam-Apps-Management-API
A basic Steam Application Management API and Valve Data Format (VDF) reader/writer.
Stars: ✭ 24 (+33.33%)
Mutual labels:  events, listener, process
iworker
Promise-based wrapper for worker_threads
Stars: ✭ 18 (+0%)
Mutual labels:  worker, promise, threads
jetemit
jetemit is an event manager for React, React Native, Vue, Angular, and all javascript project
Stars: ✭ 44 (+144.44%)
Mutual labels:  events, listener
Hamsters.js
100% Vanilla Javascript Multithreading & Parallel Execution Library
Stars: ✭ 517 (+2772.22%)
Mutual labels:  worker, thread
Toolkit
Collection of useful patterns
Stars: ✭ 137 (+661.11%)
Mutual labels:  worker, promise
Image Promise
🎑🤞 Load one or more images, return a promise. Tiny, browser-only, no dependencies.
Stars: ✭ 129 (+616.67%)
Mutual labels:  events, promise
spa-bus
🔥Tools for multilevel components to pass values in any SPA
Stars: ✭ 15 (-16.67%)
Mutual labels:  events, listener
micro-typed-events
The smallest, most convenient typesafe TS event emitter you'll ever need
Stars: ✭ 39 (+116.67%)
Mutual labels:  events, listener
YACLib
Yet Another Concurrency Library
Stars: ✭ 193 (+972.22%)
Mutual labels:  promise, thread
ikisocket
🧬 WebSocket wrapper with event management for Fiber https://github.com/gofiber/fiber. Based on Fiber WebSocket and inspired by Socket.io
Stars: ✭ 92 (+411.11%)
Mutual labels:  events, listener
wtsqs
Simplified Node AWS SQS Worker Wrapper
Stars: ✭ 18 (+0%)
Mutual labels:  worker, promise
Greenlet
🦎 Move an async function into its own thread.
Stars: ✭ 4,511 (+24961.11%)
Mutual labels:  worker, thread
Post Me
📩 Use web Workers and other Windows through a simple Promise API
Stars: ✭ 398 (+2111.11%)
Mutual labels:  worker, promise
Alloy Worker
面向事务的高可用 Web Worker 通信框架
Stars: ✭ 349 (+1838.89%)
Mutual labels:  worker, thread
Before After Hook
wrap methods with before/after hooks
Stars: ✭ 49 (+172.22%)
Mutual labels:  events, promise
Promise
Promise-在Java中以同步的方式异步编程
Stars: ✭ 20 (+11.11%)
Mutual labels:  promise, thread
Q
A platform-independent promise library for C++, implementing asynchronous continuations.
Stars: ✭ 179 (+894.44%)
Mutual labels:  promise, thread
Thread
type safe multi-threading made easier
Stars: ✭ 34 (+88.89%)
Mutual labels:  worker, thread
transceiver
Channel based event bus with request/reply pattern, using promises. For node & browser.
Stars: ✭ 25 (+38.89%)
Mutual labels:  events, promise

event-worker

Minimalistic event/promified driven web worker abstraction.

Build Status npm version JavaScript Style Guide

Install

npm

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):

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:

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):

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):

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):

//...

worker.on('interestingData', ({payload})=>{

  doSomethingWithInterestingData(payload)

  return 'Good job worker!'

})

//..

From worker (worker.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):

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.

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):

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):

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:

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<any>

    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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].