make-asynchronous
Make a synchronous function asynchronous by running it in a worker
This makes it super simple to offload some expensive work without having to deal with the complex Web Workers API.
Please upvote this Node.js issue 🙏 It would let us simplify the code.
Works in Node.js and browsers.
Install
npm install make-asynchronous
Usage
import makeAsynchronous from 'make-asynchronous';
const fn = makeAsynchronous(number => {
return performExpensiveOperation(number);
});
console.log(await fn(2));
//=> 345342
API
makeAsynchronous(function, options?)
Returns a wrapped version of the given function which executes asynchronously in a background thread (meaning it will not block the main thread).
The given function is serialized, so you cannot use any variables or imports from outside the function scope. You can instead pass in arguments to the function.
makeAsynchronousIterable(function, options?)
Make the iterable returned by a function asynchronous by running it in a worker.
The given function is serialized, so you cannot use any variables or imports from outside the function scope. You can instead pass in arguments to the function.
import {makeAsynchronousIterable} from 'make-asynchronous';
const fn = makeAsynchronousIterable(function * (number) {
yield * performExpensiveOperation(number);
});
for await (const number of fn(2)) {
console.log(number);
}
options
Type: object
The options are the same for makeAsynchronous and makeAsynchronousIterable.
baseUrl
Type: string | URL
Base URL used to resolve bare dynamic imports in Node.js workers.
Pass import.meta.url when the function dynamically imports dependencies from the module that creates the wrapper.
import makeAsynchronous from 'make-asynchronous';
const fn = makeAsynchronous(async () => {
const {default: package_} = await import('package-owned-by-this-module');
return package_;
}, {
baseUrl: import.meta.url,
});
fn.withSignal(signal)
The function returned by makeAsynchronous and makeAsynchronousIterable has an additional method which allows an AbortSignal to be provided.
import makeAsynchronous from 'make-asynchronous';
const fn = makeAsynchronous(number => {
return performExpensiveOperation(number);
});
const controller = new AbortController();
const timeoutId = setTimeout(() => {
controller.abort();
}, 1000); // 1 second timeout
const result = await fn.withSignal(controller.signal)(2);
clearTimeout(timeoutId);
console.log(result);
//=> 345342