Skip to content

Instantly share code, notes, and snippets.

@literallylara
Last active April 27, 2022 19:07
Show Gist options
  • Save literallylara/d360e2c0b048f2a56a7bd25f3563da7f to your computer and use it in GitHub Desktop.
Save literallylara/d360e2c0b048f2a56a7bd25f3563da7f to your computer and use it in GitHub Desktop.
/**
* Promise wrapper for web workers.
*
* @author Lara Sophie Schütt (@literallylara)
* @license MIT
*/
export default class PromiseWorker
{
constructor(fn, ...args)
{
return new Promise((resolve, reject) =>
{
if (typeof fn != "function")
{
reject("Expected function at first argument")
return
}
const script = `onmessage = e => postMessage((${fn})(...e.data))`
const url = "data:application/javascript;base64," + btoa(script)
const worker = new Worker(url)
worker.onmessage = e =>
{
resolve(e.data)
worker.terminate()
}
worker.onmessageerror = worker.onerror = e =>
{
reject(e)
worker.terminate()
}
worker.postMessage(args)
})
}
}
@literallylara
Copy link
Author

Example usage:

import PromiseWorker from "./promise-worker.js"

// Calculate all primes up to a million
new PromiseWorker(limit =>
{
    const primes = []
    
    function isPrime(n)
    {
        let d = Math.floor(Math.sqrt(n)) + 1

        while (d > 1) if (n%(d--) == 0) return false

        return true
    }
    
    for (let i = 1; i < limit; i++)
    {
        if (isPrime(i)) primes.push(i)
    }
    
    return primes

}, 1e6)
.then(primes =>
{
    // [1, 3, 5, 7, ..., 999983]
    console.log(primes)
})
.catch(err =>
{
    console.log(err)
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment