promise-array-parallel
Language Support
- English
- 日本語
Overview
PromiseArrayParallel is a utility library that simplifies the parallel execution of asynchronous tasks with the same ease as Promise.all() or .map(). This library allows you to efficiently manage multiple asynchronous processes while controlling concurrency levels and execution order.
Main Features:
- Parallel execution of asynchronous tasks
- Limit on the number of concurrently running tasks
- Execution order control (“completion order” or “index order”)
- Interval setting between tasks
- Error handling
Installation
npm
npx jsr add @gunseikpaseri/promise-array-parallelDeno
deno add jsr:@gunseikpaseri/promise-array-parallelUsage
Basic Usage
import { PromiseArray } from "./promise-array-parallel.ts";
// Create a PromiseArray instance from an array
const result = await PromiseArray
.from([1, 2, 3, 4, 5])
// Perform some asynchronous operation on each item
.asyncMap(async ({ value, idx }) => {
return value * 2;
}, { maxExecutionSlots: 3 }) // Run a maximum of 3 tasks in parallel
.all(); // Get all results
console.log(result); // [2, 4, 6, 8, 10]Multiple Processing Pipelines
const result = await PromiseArray
.from([1, 2, 3, 4, 5])
.asyncMap(async ({ value }) => {
// First operation
return value * 2;
}, { maxExecutionSlots: 3 })
.asyncMap(async ({ value }) => {
// Second operation (receives the result of the first operation)
return value + 10;
}, { maxExecutionSlots: 2 }) // Run with a different concurrency level
.all();
console.log(result); // [12, 14, 16, 18, 20]Controlling Execution Order
Completion Order (COME)
Using the priority: "COME" option ensures that tasks are executed in the order they finish.
const result = await PromiseArray
.from(data)
.asyncMap(async () => {
// Processing
}, { maxExecutionSlots: 20 })
.asyncMap(async ({ value }) => {
// Execute in completion order
}, { maxExecutionSlots: 10, priority: "COME" })
.all();When executing two tasks on seven elements with a concurrency of 3, the execution order is as follows:
gantt
title Task Execution Order: COME
dateFormat HH:mm:ss
axisFormat %M:%S
section Object 1
Task A(1): crit, a1, 00:00:00, 2s
Task B(1): active, b1, after a1, 3s
section Object 2
Task A(2): crit, a2, 00:00:00, 4s
Task B(2): active, b2, after a2, 1s
section Object 3
Task A(3): crit, a3, 00:00:00, 3s
Task B(3): active, b3, after a3, 1sIndex Order (INDEX)
Using the priority: "INDEX" option ensures tasks are executed in the original array order, even if it takes longer than COME. This is useful when you need to process asynchronous functions in sequence.
const result = await PromiseArray
.from(data)
.asyncMap(async () => {
// Processing
}, { maxExecutionSlots: 20 })
.asyncMap(async ({ value }) => {
// Execute in index order
}, { maxExecutionSlots: 10, priority: "INDEX" })
.all();For seven elements with two tasks running in parallel (concurrency of 3), the execution order is as follows:
gantt
title Task Execution Order: INDEX
dateFormat HH:mm:ss
axisFormat %M:%S
section Object 1
Task A(1): crit, a1_i, 00:00:00, 2s
Task B(1): active, b1_i, after a1_i, 3s
section Object 2
Task A(2): crit, a2_i, 00:00:00, 4s
Task B(2): active, b2_i, after a2_i, 1s
section Object 3
Task A(3): crit, a3_i, 00:00:00, 3s
Task B(3): active, b3_i, after a2_i, 1sError Handling
When calling PromiseArray.all(), if any task fails, the entire process will stop. Similar to Promise.allSettled([...]) in contrast to Promise.all([...]), you can use PromiseArray.allSettled() for error handling.
const results = await PromiseArray
.from(data)
.asyncMap(async ({ idx }) => {
if (condition) throw new Error("Error occurred");
// Processing
})
.allSettled();
// Includes both successful and failed task results
results.forEach((result, index) => {
if (result.status === "fulfilled") {
console.log(`Task ${index} succeeded:`, result.value);
} else {
console.log(`Task ${index} failed:`, result.reason);
}
});Setting Intervals
Using the executionIntervalMS option, you can set an interval between parallel tasks, delaying their start times.
const result = await PromiseArray
.from(data)
.asyncMap(async () => {
// Processing
}, { maxExecutionSlots: 20, executionIntervalMS: 20 }) // 20ms interval between task starts
.all();