Package Exports
- busywait
- busywait/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (busywait) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
busywait.js
Simple Async busy wait module for Node.JS
Main features
- Simple api to busy wait for a desired outcome
- Exponential backoff (with optional full jitter) support
- Slim library (single file, 100 lines of code, no dependencies)
- Full typescript support
Quick example
import {busywait} from 'busywait';
const waitUntil = Date.now() + 2500;
const checkFn = async (iteration: number, delay: number, totalDelay: number): Promise<string> => {
console.log(`Running iteration ${iteration} after delay of ${delay}ms and total delay of ${totalDelay}`);
if (Date.now() > waitUntil) {
return `success`;
}
throw new Error('custom error');
};
(async () => {
const result = await busywait(checkFn, {
sleepTime: 500,
maxChecks: 20,
})
console.log(`Finished after ${result.backoff.time}ms (${result.backoff.iterations} iterations) with result ${result.result}`);
})();
Will result in:
Running iteration 1 after delay of 0ms and total delay of 1
Running iteration 2 after delay of 500ms and total delay of 504
Running iteration 3 after delay of 500ms and total delay of 1007
Running iteration 4 after delay of 500ms and total delay of 1508
Running iteration 5 after delay of 500ms and total delay of 2010
Running iteration 6 after delay of 500ms and total delay of 2511
Finished after 2511ms (6 iterations) with result success
Exponential backoff
import {busywait} from 'busywait';
const waitUntil = Date.now() + 2500;
const checkFn = async (iteration: number, delay: number, totalDelay: number): Promise<string> => {
console.log(`Running iteration ${iteration} after delay of ${delay}ms and total delay of ${totalDelay}`);
if (Date.now() > waitUntil) {
return `success`;
}
throw new Error('custom error');
};
(async () => {
const result = await busywait(checkFn, {
sleepTime: 100,
jitter: 'none',
multiplier: 2,
})
console.log(`Finished after ${result.backoff.time}ms (${result.backoff.iterations} iterations) with result ${result.result}`);
})();
Will result in:
Running iteration 1 after delay of 0ms and total delay of 1
Running iteration 2 after delay of 100ms and total delay of 104
Running iteration 3 after delay of 200ms and total delay of 306
Running iteration 4 after delay of 400ms and total delay of 707
Running iteration 5 after delay of 800ms and total delay of 1509
Running iteration 6 after delay of 1600ms and total delay of 3110
Finished after 3110ms (6 iterations) with result success
Exponential backoff with full jitter
import {busywait} from 'busywait';
const waitUntil = Date.now() + 2500;
const checkFn = async (iteration: number, delay: number, totalDelay: number): Promise<string> => {
console.log(`Running iteration ${iteration} after delay of ${delay}ms and total delay of ${totalDelay}`);
if (Date.now() > waitUntil) {
return `success`;
}
throw new Error('custom error');
};
(async () => {
const result = await busywait(checkFn, {
sleepTime: 100,
jitter: 'full',
multiplier: 2,
waitFirst: true,
})
console.log(`Finished after ${result.backoff.time}ms (${result.backoff.iterations} iterations) with result ${result.result}`);
})();
Will result in:
Running iteration 1 after delay of 31ms and total delay of 31
Running iteration 2 after delay of 165ms and total delay of 199
Running iteration 3 after delay of 217ms and total delay of 417
Running iteration 4 after delay of 378ms and total delay of 796
Running iteration 5 after delay of 1397ms and total delay of 2195
Running iteration 6 after delay of 1656ms and total delay of 3853
Finished after 3853ms (6 iterations) with result success
Install
npm install busywait
Parameters
checkFn
A function that takes a single optional argument, which is the current iteration number.
Args
iteration
- The current iteration number (starting from 1)delay
- The last delay (in ms) that was appliedtotalDelay
- The total delay (in ms) applied so far
Return
Either:
- a non promised value (in which case, a failed check should throw an error)
- a promised value (in which case, a failed check should return a rejected promise)
options
mandatory
sleepTime
- Time in ms to wait between checks. In the exponential mode, will be the base sleep time.
optional
multiplier
- The exponential multiplier. Set to 2 or higher to achieve exponential backoff (default: 1 - i.e. linear backoff)maxDelay
- The max delay value between checks in ms (default: infinity)maxChecks
- The max number of checks to perform before failing (default: infinity)waitFirst
- Should we wait thesleepTime
before performing the first check (default: false)jitter
- ('none' | 'full') The jitter mode to use (default: none)failMsg
- Custom error message to reject the promise with
Return value
Return value is a promise.
- The promise will be resolved if the
checkFn
was resolved within a legal number of checks. - The promise will be rejected if the
checkFn
rejected (or threw an error)maxChecks
times.
Promise resolved value:
backoff.iterations
- The number of iterations it took to finishbackoff.time
- The number of time it took to finishresult
- The resolved value ofcheckFn
Contributing
All contributions are happily welcomed!
Please make all pull requests to the master
branch from your fork and ensure tests pass locally.