npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

async-tasks-runner

v1.0.1

Published

Run tasks in parallel, serial & pipeline.

Downloads

219

Readme

Async Tasks Runner

npm version npm downloads minzip treeshakable Github Actions CI License

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.

Async Tasks Runner

⚠️ 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

  1. Add async-tasks-runner dependency with yarn or npm to your project
yarn add async-tasks-runner

# or

npm install async-tasks-runner
  1. 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:

  1. standby: The runner is open to adding or removing tasks. This status actually present that the runner is not started yet!
  2. 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.
  3. 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.
  4. rejected: In this status, the runner did its job but with an error in the process, and the whole run is rejected. Like fulfilled 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

  1. Fork this repository
  2. Install dependencies using yarn install or npm install
  3. Making your changes
  4. Run the yarn lint command
  5. Run the yarn test command
  6. Push and make a PR

License

MIT License

Copyright (c) Mohammad Saleh Fadaei (@ms-fadaei)