Security News
Node.js EOL Versions CVE Dubbed the "Worst CVE of the Year" by Security Experts
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
asva-executors
Advanced tools
Helper classes for your async flow control.
npm install asva-executors
yarn add asva-executors
Conceptually, executors are just wrappers for asynchronous commands (functions). Yet they possess the following benefits:
executor.isRunning
tells whether executor runs command or not. Vanilla JS solutions often involve flags and are much clunkier.Executors are low-level concept and might require a bit of time to wrap your head around. After that they're intuitive and fun to use.
This library was not born on the spot and classes were used in various applications big and small by multiple developers for more than a year. Expect it to be reasonably refined and well thought.
Library is armed with TypeScript declarations and tests.
Available classes are:
setInterval
wrapped in class.Here are some possible use cases:
You may have noticed that we have Executor
classes and Loader
classes.
Executor's constructor takes in a function that returns promise, and, as a result provides better async flow control.
const executor = new Executor(functionThatReturnsPromise)
await executor.run()
await executor.run()
Loader's constructor requires specific arguments, different for each case. run
function won't return Promise. Asyncronous handling is loader internal.
const loader = new Loader(genericFunction)
loader.run()
import { Executor } from 'asva-executors'
// This command is just example. Yours should still return promise but hopefully be more useful : 3.
const command = response => Promise.resolve(response)
// Instantiate executor
const executor = new Executor(command)
// Run command and process results
executor.run('data').then(result => console.log(result)) // Outputs 'data' to console
// Instantiate executor and run immediately
const executor = Executor.createAndRun(command)
// Do some checks
executor.isRunning // Tells if executor currently runs command.
executor.runCount // Show the number of currently running commands. There could be more than one, yes.
executor.wasRun // Executor was run at least once
executor.wasRunFine // Executor was run without throwing error at least once
executor.wasRunBad // Executor was run with thrown error at least once
executor.wasLastRunFine // Last executor run happened without an error
// We intend to make an expensive ajax call from several places.
import { CacheExecutor } from 'asva-executors'
const executor = new CacheExecutor(ajaxExpensiveCall)
// Run the same executor in a number of places simultaneously or not.
// Command will be executed only once.
const result = await executor.run()
// If you have to load anew.
executor.runFresh()
// This example is live search.
import { LadderExecutor } from 'asva-executors'
const executor = new Executor(liveSearchCall)
// Imagine the case when user takes a nap on his keyboard.
executor.run('a') // This request will be run
executor.run('aa') // This request won't be run
executor.run('aaa') // This request won't be run
executor.run('aaaa') // This request will be run only after first one resolves.
// So, in total you have 2 requests instead of 4.
// Example is simple select that manages its own state.
import { StatefulExecutor } from 'asva-executors'
const executor = new StatefulExecutor(command, []) // if you don't provide second argument, default state is `null`
executor.state // will be initially []
await executor.run()
executor.state // Now becomes whatever was returned from `command`.
// In test environment we want to observe data or DOM change when we don't have any event handle.
import { RetrierExecutor } from 'asva-executors'
// We will check observed property every 10ms for 1000ms at max.
const retrierExecutor = new RetrierExecutor(() => property === expectedValue, 10, 1000)
// `run` returns normal promise
await retrierExecutor.run()
If 1000ms passes and condition is not yet fullfilled - promise will reject.`
// We want to save the form if user was inactive for 3 seconds.
import { DebounceLoader } from 'asva-executors'
const loader = new DebounceLoader(saveTheForm, 3000)
// User starts editing the form
loader.run()
// And does that a couple of times in quick succession.
loader.run()
loader.run()
// Then he stops. 3 seconds pass. And only then `saveTheForm` command is called.
// User starts editing the form again.
loader.run()
// Then goes to another page. We want to stop execution.
loader.reset()
DebounceLoader has several public properties:
loader.isRunning // Means command is currently executing.
loader.isWaiting // Executor is waiting the period of inactivity to finish.
loader.isActive // Executor is running or is waiting.
// Being too lazy to implement websockets we decide to check notifications every ten seconds.
import { RepeatLoader } from 'asva-executors'
const loader = new RepeatLoader(checkNotificationsCall, 10000)
// Start checking notifications
loader.start()
// Stop checking notifications
loader.stop()
You have to stop RepeatLoader
if you don't need it anymore. Similar to setInterval
command it won't be garbage collected until then.
// This example is lazy loaded list of items.
import { InfiniteLoader } from 'asva-executors'
/**
* Constructor takes in two arguments:
*
* * command, which is a function that takes in
* - `pointer` (position in list, OFFSET in sql),
* - `perStep` (number of items per request, LIMIT in sql);
* and returns promise with a specified number of items.
* If length of items loaded is less than `perStep`, loader
* would consider itself finished and won't trigger anymore.
*
* * perStep - number of items per request (defaults to 20)
*/
const loader = new InfiniteLoader(
async (pointer, perStep) => await loadListItems(pointer, perStep),
10
)
// User opens the page.
loader.next() // Loader begins to load first 10 items.
// User scrolls down impatiently.
loader.next() // This command will be ignored silently as first request is still in progress.
// User waits for list to be downloaded.
console.log(loader.items.length) // > 10
// User read through first 10 items and he wants more.
loader.next() // Loads next 10 items
// And they're swiftly loaded.
console.log(loader.items.length) // > 20
// User decides to apply a filter because scrolling is hard.
loader.refresh() // Starts request to load items anew. Old items are left intact until request finishes.
// List is refreshed with new filter.
console.log(loader.items.length) // > 10
// To access your items call.
loader.items
// You can perform various checks on `InfiniteLoader` instance:
loader.isRunning // Loader is running
loader.isEmpty // We tried to load, but list is empty
loader.ifFull // We tried to load, and list is not empty
loader.isRefreshing // Is loading anew (refreshing or loading for first time).
Feel free to check source code or tests to get better understanding. Library exposes typings so your IDE should comfortably provide type-hinting.
MIT
FAQs
Helper classes for your async flow control
The npm package asva-executors receives a total of 184 weekly downloads. As such, asva-executors popularity was classified as not popular.
We found that asva-executors demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
Security News
cURL and Go security teams are publicly rejecting CVSS as flawed for assessing vulnerabilities and are calling for more accurate, context-aware approaches.
Security News
Bun 1.2 enhances its JavaScript runtime with 90% Node.js compatibility, built-in S3 and Postgres support, HTML Imports, and faster, cloud-first performance.