task-handler

A simple, dependency-free task scheduling manager that makes it easy to handle tasks like a boss.
Install
yarn add task-handler
or
npm install --save task-handler
Coverage
Flow
This project provides .flow.js files for Flow to utilize. It also attempts to provide near-100% test coverage.
Typescript
This project provides the appropriate index.d.ts file for TypeScript users.
Example
Simple
import createTaskHandler from "task-handler";
const task = createTaskHandler("simple");
const refOne = task.after("task:one", 3000, () => log("task:one execute"));
const refTwo = task.every("task:two", 3000, () => log("task:two execute"));
const refThree = task.defer("task:three", () => log("task:three execute"));
const refFour = task.everyNow("task:four", 3000, () =>
log("task:four execute")
);
const refFive = task.everySequential("task:five", 100, async () => {
log("task:five execute");
await new Promise(resolve => setTimeout(resolve, 3000));
log("task:five completes");
});
const refSix = task.everyNowSequential("task:six", 100, async () => {
log("task:six execute");
await new Promise(resolve => setTimeout(resolve, 3000));
log("task:six completes");
});
const refSeven = task.job(
"task:seven",
function TaskFiveHandler(...args) {
const ref = this;
return {
async start(ref2) {
},
async cancelled() {
},
async complete() {
}
};
},
[1, 2, 3]
);
task.size;
task.cancel("task:one", "task:two");
task.after("complete", 10000, () => {
log("complete - clearing tasks");
task.clear();
});
Features / Summaries
Auto Cancellation
Creating a task with the same id as another task will cancel the previous task and schedule the next automatically.
Refs
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 = {|
+id: any,
+type: Task$Types,
get result(): any,
get promise(): () => Task$Promise$Regular,
get promises(): () => Task$Promise$Every,
+status: {
resolving: boolean,
complete: boolean,
cancelled: boolean,
error: boolean
},
cancel(): void,
resolve(value: any): void,
reject(reason: any): void,
task: Task$Handler
|};
For the complete types, view types.js.
Promises
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);
});
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");
ref.cancel();
}
console.log("After Cancel everyID");
}
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");
ref.cancel();
}
console.log("After Cancel everyID");
}
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);
}
}
}