Security News
The Risks of Misguided Research in Supply Chain Security
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.
task-handler
Advanced tools
Handle Javascript Timers like a boss! https://odo-network.github.io/task-handler/
A simple, dependency-free task scheduling manager that makes it easy to handle tasks like a boss.
yarn add task-handler
or
npm install --save task-handler
This project provides .flow.js
files for Flow
to utilize. It also attempts to provide near-100% test coverage.
This project provides the appropriate index.d.ts
file for TypeScript users.
/* @flow */
import createTaskHandler from "task-handler";
const task = createTaskHandler("simple");
// after timeout
const refOne = task.after("task:one", 3000, () => log("task:one execute"));
// every interval, execute
const refTwo = task.every("task:two", 3000, () => log("task:two execute"));
// immediately execute on next tick (nextTick, immediate, timeout priority - first found)
const refThree = task.defer("task:three", () => log("task:three execute"));
// every interval and immediately (defer), execute
const refFour = task.everyNow("task:four", 3000, () =>
log("task:four execute")
);
// sequentially execute at an interval -
// waits until the function requested to
// finish before scheduling the next
// timeout.
// - NOTE: Awaits promises if returned
// by the function. Which is not
// the standard behavior.
const refFive = task.everySequential("task:five", 100, async () => {
log("task:five execute");
await new Promise(resolve => setTimeout(resolve, 3000));
log("task:five completes");
});
// same as above but adds a deferred execution first
// which occurs on the next tick.
const refSix = task.everyNowSequential("task:six", 100, async () => {
log("task:six execute");
await new Promise(resolve => setTimeout(resolve, 3000));
log("task:six completes");
});
// schedule an advanced async job with cancellation
const refSeven = task.job(
"task:seven",
function TaskFiveHandler(...args) {
// args resolves to [ref, 1, 2, 3]
// saved context - `this` resolves to the job `ref`
const ref = this;
return {
async start(ref2) {
// called when the job starts (synchronously)
//
// ref is also the first argument given, it is the same as the
// top level `this` but can be used when using arrow function
// at the top level.
// ref.resolve('value');
// ref.reject('error');
// ref.cancel();
},
async cancelled() {
// called if the job is cancelled
},
async complete() {
// called when the job is complete (resolved, cancelled, or errored).
}
};
},
[1, 2, 3]
);
// get the total # of tasks scheduled
task.size; // 7
// cancels each of the given ID's, if they exist
task.cancel("task:one", "task:two");
// clear all tasks, killing the event queue and completing execution
task.after("complete", 10000, () => {
log("complete - clearing tasks");
task.clear();
});
Creating a task with the same id
as another task will cancel the previous task and schedule the next automatically.
task-handler
implements a concept of task refs
so that we can provide a unified API across all of the event types.
When using promises
, the promise will be resolved with the ref
for the task which allows capturing the result via ref.result
.
If an error is caught, the error object will include the ref as a property.
export type Task$Types = "after" | "every" | "defer" | "job";
export type Task$Ref = {|
/* Task ID */
+id: any,
/* indicates the general type of the task */
+type: Task$Types,
/* the result of executing the tasks handler */
get result(): any,
/* returns a promise that resolves to the next result.
if the task is an 'every' type, it must be called
after every execution to continually get the next
promise (or use ref.promises() instead). */
get promise(): () => Task$Promise$Regular,
/* async iterator that provides results for each iteration. May only be called on 'every' type tasks. */
get promises(): () => Task$Promise$Every,
/* Status about the task */
+status: {
/* Task is resolving by calling its execute handler */
resolving: boolean,
/* Task has resolved and has completed execution */
complete: boolean,
/* Task was cancelled */
cancelled: boolean,
/* Task encountered an error */
error: boolean
},
/* Cancels the task, an alias for `task.cancel(ref.id)` */
cancel(): void,
/* Resolves the task with the value provided. */
resolve(value: any): void,
/* Rejects the event and calls the error handling
that is present on the task (if any). Generally
used for `task.job` but works with any active
task. */
reject(reason: any): void,
/* top-level task handler the ref belongs to */
task: Task$Handler
|};
For the complete types, view types.js.
When calling .promise()
on the task ref, after
and defer
return regular promises that resolve to the task ref with a result of the function passed. If no function is passed then the ref.result
will be undefined.
task
.after("afterID", 1000, () => 1)
.promise()
.then(ref => {
console.log("After 1000ms: ", ref.result); // After 1000ms: 1
});
Interval tasks such as every
and everyNow
return async iterators
when their .promises()
function is called. This allows us to utilize the handy for await... of
feature of JS.
IMPORTANT: Notice that
every
,everySequential
, and their related siblings use.promises()
and.promise()
. If other functions call.promises()
which are not interval types they will throw an error.
async function intervalForAwait() {
const ref = task.every("everyID", 1000);
for await (const ref of ref.promises()) {
console.log("Next Tick");
// based on some logic...
ref.cancel();
}
console.log("After Cancel everyID");
}
// Or using standard async function...
async function intervalAwait() {
const iter = task.every("everyID", 1000).promises();
let done = false;
let ref;
while (!done) {
let ref;
({ value: ref, done } = await iter.next());
console.log("Next Tick");
// based on some logic...
ref.cancel();
}
console.log("After Cancel everyID");
}
// if we want to handle errors that are not caught
// in the task runner we can utilize a while loop:
async function awaitResults(ref) {
const ref = task.every(
"everyID",
1000,
() => throw new Error("Error Message")
);
while (true) {
try {
for await (const result of ref.promises()) {
console.log("Tick!");
}
return;
} catch (e) {
console.log("Error!", e);
}
}
}
FAQs
Handle Javascript Timers like a boss! https://odo-network.github.io/task-handler/
The npm package task-handler receives a total of 6 weekly downloads. As such, task-handler popularity was classified as not popular.
We found that task-handler 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
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.
Research
Security News
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.