async-tasks-runner
v1.0.1
Published
Run tasks in parallel, serial & pipeline.
Downloads
192
Maintainers
Readme
Async Tasks Runner
tiny (~ 1kb gzipped), side-effect free, tree shakable, zero dependencies, and fully typed Tasks Runner. Run your tasks in parallel, serial & pipeline in a more complicated and performant way.
With this module you can run your tasks in 3 different ways:
- Parallel: Run your independent tasks in parallel. The result is an array, like the
Promise.allSettled
result. - Serial: Run your independent tasks in sequence. The result is an array, like the
Promise.allSettled
result. - Pipeline: Run your dependent tasks in sequence. The result of every task will be passed to the next task.
⚠️ Attention: This package comes without any polyfills. If you want to support an older environment, please polyfills it depending on what you need.
- ES2015
- ES2017 async/await
- ES2020 Promise.allSettled (Just for the ParallelTasksRunner)
Setup
- Add
async-tasks-runner
dependency withyarn
ornpm
to your project
yarn add async-tasks-runner
# or
npm install async-tasks-runner
- Use it everywhere you want
// ES Module
import {createParallelTasksRunner, runParallelTasks, getParallelTasks} from "async-tasks-runner"
// CJS
const {createParallelTasksRunner, runParallelTasks, getParallelTasks} = require("async-tasks-runner")
Runners
| Runner | Example | | ------ | ------- | | ParallelTasksRunner | See Examples | | SerialTasksRunner | See Examples | | PipelineTasksRunner | See Examples |
Global Helper Functions
| Functions | Description| Parameter(s) | Return Value | | ------ | ------- | ------ | ------- | | pushTasks | push tasks to the runner. See pushTasks Section | taskRunnerObject, tasks[] | number: the new length of tasks | | spliceTasks | removing or replacing existing tasks and/or adding new elements in place See spliceTasks Section | taskRunnerObject, startIndex, deleteCount, newTasks[] | array: list of removed tasks | | getTasksRunnerStatus | current status of the runner. See getTasksRunnerStatus Section | taskRunnerObject | string: status |
pushTasks
With this function, you can push new tasks to the runner (like Array.prototype.push()
).
pushTasks(taskRunnerObject, ...newTasks[]);
spliceTasks
With this function, you can change the contents of an array by removing or replacing existing elements and/or adding new elements in place (like Array.prototype.splice()
).
spliceTasks(taskRunnerObject, start, deleteCount, ...newTasks[] );
getTasksRunnerStatus
With this function, you can get the current status of the runner.
const currentStatus = getTasksRunnerStatus(taskRunnerObject)
This function returns 4 different statuses:
standby
: The runner is open to adding or removing tasks. This status actually present that the runner is not started yet!pending
: Represent that the runner starts pending the tasks and in the meantime, you can't nor add/remove tasks to/from the runner neither reset the runner.fulfilled
: Represent that the runner did its job and now you can get the result or reset the runner to add/remove tasks to/from the runner and run them again.rejected
: In this status, the runner did its job but with an error in the process, and the whole run is rejected. Likefulfilled
status, you can reset the runner to add/remove tasks to/from the runner and run them again.
Examples
Parallel Tasks Runner
You can run your tasks in parallel. the result is an array, like the Promise.allSettled
result.
Create
You can create a parallel task runner object by the calling of createParallelTaskRunner
. The result will be an object that must be passed as the first argument to any helper functions that you want to use.
import {createParallelTasksRunner} from "async-tasks-runner"
const taskRunnerObject = createParallelTasksRunner(...tasks);
Every task in the ParallelTasksRunner
must be a function without a parameter and return a promise.
const url = "https://google.com";
const task1 = () => {
return fetch(`${url}/first`);
}
const task2 = () => {
return fetch(`${url}/second`);
}
const taskRunnerObject = createParallelTasksRunner(task1, task2);
Run
Start pending the runner. When it is called, the status changed to pending
and when it is done, the status changed to fulfilled
. If you run it again, it's not starting to run again and fulfilled with the previous result unless you reset the runner. This means you can start the runner then do some heavy work and call it again to get the result without getting the process blocked! This method returns a promise that resolves after all of the given promises have either been fulfilled or rejected, with an array of objects that each describes the outcome of each promise.
import {runParallelTasks} from "async-tasks-runner"
const result = await runParallelTasks(taskRunnerObject);
// [
// {status: "fulfilled", value: 33},
// {status: "fulfilled", value: 66},
// {status: "fulfilled", value: 99},
// {status: "rejected", reason: Error: an error}
// ]
Result of Specific Task
After running the runner (no matter of status is pending
or fulfilled
or rejected
), you can access a specific task with this method. The only parameter of this method is the index of the task. This method returns a Promise that resolves with the task result or is rejected with the current or previous task rejection.
import {getParallelTasks} from "async-tasks-runner"
const result = await getParallelTasks(taskRunnerObject, 0);
Clone
You can clone tasks of your runner and create a new tasks runner.
import {createParallelTasksRunner} from "async-tasks-runner"
const newTaskRunnerObject = createParallelTasksRunner(...taskRunnerObject.tasks);
Serial Tasks Runner
You can run your tasks in sequence. the result is an array, like the Promise.allSettled
result.
Create
You can create a serial task runner object by the calling of createSerialTaskRunner
. The result will be an object that must be passed as the first argument to any helper functions that you want to use.
import {createSerialTasksRunner} from "async-tasks-runner"
const taskRunnerObject = createSerialTasksRunner(...tasks);
Every task in the SerialTasksRunner
must be a function without a parameter and return a promise.
const url = "https://google.com";
const task1 = () => {
return fetch(`${url}/first`);
}
const task2 = () => {
return fetch(`${url}/second`);
}
const taskRunnerObject = createSerialTasksRunner(task1, task2);
Run
Start pending the runner. When it is called, the status changed to pending
and when it is done, the status changed to fulfilled
. If you run it again, it's not starting to run again and fulfilled with the previous result unless you reset the runner. This means you can start the runner then do some heavy work and call it again to get the result without getting the process blocked! This method returns a promise that resolves after all of the given promises have either been fulfilled or rejected, with an array of objects that each describes the outcome of each promise.
import {runSerialTasks} from "async-tasks-runner"
const result = await runSerialTasks(taskRunnerObject);
// [
// {status: "fulfilled", value: 33},
// {status: "fulfilled", value: 66},
// {status: "fulfilled", value: 99},
// {status: "rejected", reason: Error: an error}
// ]
Result of Specific Task
After running the runner (no matter of status is pending
or fulfilled
or rejected
), you can access a specific task with this method. The only parameter of this method is the index of the task. This method returns a Promise that resolves with the task result or is rejected with the current or previous task rejection.
import {getSerialTasks} from "async-tasks-runner"
const result = await getSerialTasks(taskRunnerObject, 0);
Clone
You can clone tasks of your runner and create a new tasks runner.
import {createSerialTasksRunner} from "async-tasks-runner"
const newTaskRunnerObject = createSerialTasksRunner(...taskRunnerObject.tasks);
Pipeline Tasks Runner
You can run your tasks in sequence. The result of the currently pending task will be the argument of the next task.
Create
You can create a serial task runner object by the calling of createPipelineTaskRunner
. The result will be an object that must be passed as the first argument to any helper functions that you want to use.
import {createPipelineTasksRunner} from "async-tasks-runner"
const taskRunnerObject = createPipelineTasksRunner(...tasks);
Every task in the PipelineTasksRunner
must be a function that returns a promise. This function can accept one parameter that will be filled with the previous fulfilled task result.
const url = "https://google.com";
const task1 = (code) => {
return fetch(`${url}/${code}`);
}
const task2 = (data) => {
return fetch(data.url);
}
const taskRunnerObject = createPipelineTasksRunner(task1, task2);
Run
With this method, you can start pending the tasks. When it is called, the status changed to pending
and when it is done, the status changed to fulfilled
if all tasks run successfully or rejected
if one of the tasks in the list get failed (and the next tasks don't get run). If you run it again, it's not starting to run again and fulfilled
or rejected
with the previous result unless you reset the runner. This means you can start the runner then do some heavy work and call it again to get the result without getting the process blocked! This method always returns a promise that resolves with the final task result or rejects with an error. The runPipelineTasks
function needs an extra argument for the parameter of the first task function (initial parameter).
import {runPipelineTasks} from "async-tasks-runner"
const result = await runPipelineTasks(taskRunnerObject, firstArgument);
// [
// {status: "fulfilled", value: 33},
// {status: "fulfilled", value: 66},
// {status: "fulfilled", value: 99},
// {status: "rejected", reason: Error: an error}
// ]
Result of Specific Task
After running the runner (no matter of status is pending
or fulfilled
or rejected
), you can access a specific task with this method. The only parameter of this method is an index of the task. This method returns a Promise that resolves with the task result or is rejected with the current or previous task failure error.
import {getPipelineTasks} from "async-tasks-runner"
const result = await getPipelineTasks(taskRunnerObject, 0);
Clone
You can clone tasks of your runner and create a new tasks runner.
import {createPipelineTasksRunner} from "async-tasks-runner"
const newTaskRunnerObject = createPipelineTasksRunner(...taskRunnerObject.tasks);
Extra Helper Functions
| Functions | Description| Parameter(s) | Return Value | | ------ | ------- | ------ | ------- | | createTimeoutResolve | create a delay with resolve | timeout: number, response: T, cancelToken?: Promise | promise | | createTimeoutReject | create a delay with reject | timeout: number, response: T, cancelToken?: Promise | promise | | createTaskWithTimeout | create a task with timeout | task: Task, timeout: number | Task
Contribution
- Fork this repository
- Install dependencies using
yarn install
ornpm install
- Making your changes
- Run the
yarn lint
command - Run the
yarn test
command - Push and make a PR
License
Copyright (c) Mohammad Saleh Fadaei (@ms-fadaei)