Installations
npm install asyncbox
Releases
Unable to fetch releases
Developer
jlipps
Developer Guide
Module System
CommonJS
Min. Node Version
>=16
Typescript Support
Yes
Node Version
18.17.0
NPM Version
10.1.0
Statistics
25 Stars
97 Commits
10 Forks
5 Watching
4 Branches
11 Contributors
Updated on 14 Nov 2024
Languages
JavaScript (100%)
Total Downloads
Cumulative downloads
Total Downloads
49,848,276
Last day
1.2%
65,419
Compared to previous day
Last week
5%
356,033
Compared to previous week
Last month
-2%
1,433,072
Compared to previous month
Last year
21.6%
16,324,330
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Dependencies
3
Dev Dependencies
20
asyncbox
A collection of ES7 async/await utilities. Install via NPM:
npm install asyncbox
Then, behold!
Sleep
An async/await version of setTimeout
1import { sleep } from 'asyncbox'; 2 3async function myFn () { 4 // do some stuff 5 await sleep(1000); // wait one second 6 // do some other stuff 7};
Long Sleep
Sometimes Promise.delay
or setTimeout
are inaccurate for large wait times. To safely wait for these long times (e.g. in the 5+ minute range), you can use longSleep
:
1import { longSleep } from 'asyncbox'; 2 3async function myFn () { 4 await longSleep(10 * 60 * 1000); // wait for 10 mins 5 await longSleep(5000, {thresholdMs: 10000}); // wait for 5s. Anything below the thresholdMs will use a single sleep 6 await longSleep(5000, {intervalMs: 500}); // check the clock every 500ms to see if waiting should stop 7}
You can also pass a progressCb
option which is a callback function that receives an object with the properties elapsedMs
, timeLeft
, and progress
. This will be called on every wait interval so you can do your wait logging or whatever.
1function progressCb({elapsedMs, timeLeft, progress}) { 2 console.log(`We are {progress * 100}% complete waiting`); 3} 4await longSleep(10 * 60 * 1000, {progressCb});
Retry
An async/await way of running a method until it doesn't throw an error
1import { sleep, retry } from 'asyncbox'; 2 3async function flakeyFunction (val1, val2) { 4 if (val1 < 10) { 5 throw new Error("this is a flakey value"); 6 } 7 await sleep(1000); 8 return val1 + val2; 9} 10 11async function myFn () { 12 let randVals = [Math.random() * 100, Math.random() * 100]; 13 14 // run flakeyFunction up to 3 times until it succeeds. 15 // if it doesn't, we'll get the error thrown in this context 16 let randSum = await retry(3, flakeyFunction, ...randVals); 17}
You can also use retryInterval
to add a sleep in between retries. This can be
useful if you want to throttle how fast we retry:
1await retryInterval(3, 1500, expensiveFunction, ...args);
Filter/Map
Filter and map are pretty handy concepts, and now you can write filter and map functions that execute asynchronously!
1import { asyncmap, asyncfilter } from 'asyncbox';
Then in your async functions, you can do:
1const items = [1, 2, 3, 4]; 2const slowSquare = async (n) => { await sleep(5); return n * 2; }; 3let newItems = await asyncmap(items, async (i) => { return await slowSquare(i); }); 4console.log(newItems); // [1, 4, 9, 16]; 5 6const slowEven = async (n) => { await sleep(5); return n % 2 === 0; }; 7newItems = await asyncfilter(items, async (i) => { return await slowEven(i); }); 8console.log(newItems); // [2, 4];
By default, asyncmap
and asyncfilter
run their operations in parallel; you
can pass false
as a third argument to make sure it happens serially.
Nodeify
Export async functions (Promises) and import this with your ES5 code to use it with Node.
1var asyncbox = require('asyncbox') 2 , sleep = asyncbox.sleep 3 , nodeify = asyncbox.nodeify; 4 5nodeify(sleep(1000), function (err, timer) { 6 console.log(err); // null 7 console.log(timer); // timer obj 8});
nodeifyAll
If you have a whole library you want to export nodeified versions of, it's pretty easy:
1import { nodeifyAll } from 'asyncbox'; 2 3async function foo () { ... } 4async function bar () { ... } 5let cb = nodeifyAll({foo, bar}); 6export { foo, bar, cb };
Then in my ES5 script I can do:
1var myLib = require('mylib').cb; 2 3myLib.foo(function (err) { ... }); 4myLib.bar(function (err) { ... });
waitForCondition
Takes a condition (a function returning a boolean or boolean promise), and waits until the condition is true.
Throws a /Condition unmet/
error if the condition has not been
satisfied within the allocated time, unless an error is provided in
the options, as the error
property, which is either thrown itself, or
used as the message.
The condition result is returned if it is not falsy. If the condition throws an error then this exception will be immediately passed through.
The default options are: { waitMs: 5000, intervalMs: 500 }
1// define your own condition
2function condFn () { return Math.random()*1000 > 995; }
3
4// with default params
5await waitForCondition(condFn);
6
7// with options
8await waitForCondition(condFn, {
9 waitMs: 300000,
10 intervalMs: 10000
11});
12
13// pass a logger to get extra debug info
14await waitForCondition(condFn, {
15 waitMs: 300000,
16 intervalMs: 10000
17 logger: myLogger // expects a debug method
18});
19
20// pass an error string to get that message in the resulting exception
21try {
22 await waitForCondition(condFn, {
23 error: 'Unable to satisfy condition'
24 });
25} catch (err) {
26 // err.message === 'Unable to satisfy condition'
27}
28
29// pass an error instance to be thrown
30const error = new Error('Unable to satisfy condition');
31try {
32 await waitForCondition(condFn, {
33 error: error
34 });
35} catch (err) {
36 // err === error
37}
Run the tests
npm test
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
no dangerous workflow patterns detected
Reason
0 existing vulnerabilities detected
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0
Reason
Found 8/24 approved changesets -- score normalized to 3
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/pr-title.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/jlipps/asyncbox/pr-title.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unit-test.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/jlipps/asyncbox/unit-test.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unit-test.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/jlipps/asyncbox/unit-test.yml/master?enable=pin
- Warn: npmCommand not pinned by hash: .github/workflows/unit-test.yml:29
- Info: 0 out of 2 GitHub-owned GitHubAction dependencies pinned
- Info: 0 out of 1 third-party GitHubAction dependencies pinned
- Info: 0 out of 1 npmCommand dependencies pinned
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/pr-title.yml:1
- Warn: no topLevel permission defined: .github/workflows/unit-test.yml:1
- Info: no jobLevel write permissions found
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'master'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 15 are checked with a SAST tool
Score
3.7
/10
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More