@sebowy/concurrent-queue

"ConcurrentQueue" organizes promises execution

Usage no npm install needed!

<script type="module">
  import sebowyConcurrentQueue from 'https://cdn.skypack.dev/@sebowy/concurrent-queue';
</script>

README

Concurrent Queue

Helps to organize promises execution

npm latest version Build states semantic-release

Installation

npm install --save @sebowy/concurrent-queue
# or
yarn add @sebowy/concurrent-queue

Usage

Examples

  • examples with timeouts
import { createConcurrentQueue } from '@sebowy/concurrent-queue';

const queue = createConcurrentQueue({
    maxConcurrency: 2,
});

const firstResult = queue.add(() => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve({name: 'First', date: new Date()});
        }, 1000)
    })
});

const secondResult = queue.add(() => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve({name: 'Second', date: new Date()});
        }, 1000)
    })
});

const thirdResult = queue.add(() => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve({name: 'Third', date: new Date()});
        }, 1000)
    })
});

firstResult.then((result) => console.log(result));
secondResult.then((result) => console.log(result));
thirdResult.then((result) => console.log(result));

will produce:

{ name: 'First', date: 2021-09-12T19:23:10.048Z }
{ name: 'Second', date: 2021-09-12T19:23:10.057Z }
# notice 1-second delay, third task was waiting for first and second tasks to resolve
{ name: 'Third', date: 2021-09-12T19:23:11.050Z }
  • example with heavy requests (every request takes 10 seconds to respond)
import { ConcurrentQueue } from "@sebowy/concurrent-queue";
import { default as fetch } from 'node-fetch';

const queue = new ConcurrentQueue({
    maxConcurrency: 3,
});

const someFunctionsToRun = Array.from(
    { length: 8 },
    (_, i) => () =>
        fetch(`https://reqres.in/api/users/${(i + 1)}?delay=10`)
            .then(response => response.json())
            .then(user =>
                console.log({ email: user.data.email, date: new Date() })),
);

const allTasks = someFunctionsToRun.map(someFunction => 
    queue.add(() => someFunction()))

Promise.all(allTasks).then(() => console.log({ date: new Date() });

will produce:

{ email: 'george.bluth@reqres.in', date: 2021-09-12T19:42:04.970Z }
{ email: 'janet.weaver@reqres.in', date: 2021-09-12T19:42:04.975Z }
{ email: 'emma.wong@reqres.in', date: 2021-09-12T19:42:04.981Z }
# notice 10-second delay after every 3 tasks
{ email: 'tracey.ramos@reqres.in', date: 2021-09-12T19:42:15.144Z }
{ email: 'charles.morris@reqres.in', date: 2021-09-12T19:42:15.154Z }
{ email: 'eve.holt@reqres.in', date: 2021-09-12T19:42:15.159Z }
# another 10-second delay
{ email: 'michael.lawson@reqres.in', date: 2021-09-12T19:42:25.315Z }
{ email: 'lindsay.ferguson@reqres.in', date: 2021-09-12T19:42:25.315Z }
# all tasks done
{ date: 2021-09-12T19:42:25.327Z }

Creating instance

  • by default factory function

    import { createConcurrentQueue } from "@sebowy/concurrent-queue";
    
    const queue = createConcurrentQueue({
        maxConcurrency: 2,
    });
    
  • by constructor

    import { ConcurrentQueue } from "@sebowy/concurrent-queue";
    
    const queue = new ConcurrentQueue({
        maxConcurrency: 2,
    });
    
  • by factory

    import { ConcurrentQueueFactory } from "@sebowy/concurrent-queue";
    
    const queueFactory = new ConcurrentQueueFactory();
    const queue = queueFactory.createConcurrentQueue({
        maxConcurrency: 2,
    });