/async-namespace

A JavaScript library which makes multithreading easy.

Primary LanguageJavaScriptMIT LicenseMIT

async-namespace library

async-namespace is a library to make multithreading in JavaScript easy. It is only available on the web. async-namespace offers high flexibility.

Documentation

To instantly jump to the examples, press here.

Table of contents

Just include the files in your HTML via a script tag, and you get access to the global asyncNamespace function.

asyncNamespace

Parameters

Name Type Optional Default Use
fn Function no void This function will have access to the function to execute code in other threads.
threads Number yes navigator.hardwareConcurrency Specifies how many threads will be generated. Usally, the default value is sufficient.You can call the values as different parameters or as object.

Example

// These are identical
asyncNamespace(myFunction, 4);
asyncNamespace({
    fn: myFunction,
    threads: 4
}); 

The fn callback function

The function you provide will be called with two arguments:

Arguments

Name Type Use
runAsync Function This function is used to run code in other threads.
threads Number The amount of threads that are available.

Example

asyncNamespace(function(runAsync,threads){
    console.log(`Using ${threads} threads.`);
    // runAsync can be used here,
    // see how to in the next point
});

The runAsync function


In the namespace, you can use this function to execute code in other threads.

Parameters

Name Type Optional Default Use
fn Function No void This function will be executed in another thread.
parameters Array or a single value Yes [] Used to import local variables into the thread. If you only provide one value and not an array, that will be used as argument. Warning: Only object which can be cloned using the structured clone algorithm can be send across threads. Trying to send invalid object will cause the promise to reject.
thread Number or false Yes automatically computed Specifies a specific thread to use. It normally iterates over the available threads and chooses the one last used.

If thread is set to false, a new thread only for fn will be created, the function will be eval'd and take no parameters.

Return value

runAsync returns a Promise.

Promise state Value
onresolve The return value of runAsync or undefined.
onreject An error object. This can have multiple reasons; all cloning errors and errors thrown while the function executes trigger onreject.

Causes for onreject

Here are the causes for a rejection of the promise. The error will be provided as argument. See below for examples.

Cause Type Message
Invalid value for fn TypeError asyncNamespace<fn>: the parameter `fn` is not a function
Invalid thread number RangeError asyncNamespace<fn>: there is no thread {thread}
Failed to clone data DOMException<DataCloneError> Failed to execute 'postMessage' on 'Worker': {Your value} could not be cloned.
Error thrown in the thread Theoretically any The error message

Examples

asyncNamespace((runAsync)=>{
    /*
    * Most simple method
    */
    runAsync(() => 1 + 1) 
        .then(result => console.log(`The result is ${result}`))
        .catch(err => console.log(`Oh no, a ${err.name} was received!`));
        // You of course dont need a catch clause
        // when working with simple values
    
    /*
     * Using parameters
     */
    let local = 5,
        local2 = -2;
    runAsync((a,b)=>a*b, [local])
        .then(result => result === -10);
        
    /*
     * A single parameter
     */
    runAsync(text => text + "World!", "Hello ")
        .then(result => console.log(result));
});

Error examples

asyncNamespace(function(runAsync, threads){

    let testFunc = a => a + 1;
    
    /*
     * Using the parameters argument
     */
    runAsync(testFunc, [5] )
        .then(result => result === 6 ); // true
        
    runAsync(testFunc, [new XMLHttpRequest] ) // error example with invalid data
        .catch(err => console.log(err));
    
    /*
     * explicit thread
     */
    runAsync(testFunc, [-5], 0)
        .then(result => result === -4 );
        // Note that the threads index starts at 0,
        // which means if you have 1 thread available
        // using the value `1` will cause a RangeError
        
    /*
     * code that will throw a runtime error
     */
    runAsync(function(){
        return new notexistingobject;    
    })
        .then(result => console.log(`The result is ${result}`))
        .catch(err => console.log(err));
});