js Promise concurrent control method

js Promise concurrent control method

question

It is required to write a method to control the number of concurrent Promises, as follows:

promiseConcurrencyLimit(limit, array, iteratorFn)

limit is the number of promises executed at the same time, array is the parameter array, and iteratorFn is the asynchronous operation performed in each promise.

background

In development, you need to execute post-processing logic after multiple promises are processed, usually using Promise.all:

Primise.all([p1, p2, p3]).then((res) => ...)

But there is a problem. Because promise is executed immediately after it is created, that is to say, multiple promise instances passed into promise.all have already started to execute when they are created. If the asynchronous operations executed in these instances are all http requests, then n http requests will be issued instantly, which is obviously unreasonable. A more reasonable way is to limit the number of asynchronous operations executed in Promise.all, and only allow limit asynchronous operations to execute simultaneously at the same time.

Idea & Implementation

As mentioned in the background, a promise is executed immediately after it is created, so the core of controlling concurrency lies in controlling the generation of promise instances. At the beginning, only limit promise instances are generated, and then wait for the status of these promises to change. As long as the status of one of the promise instances changes, another promise instance is immediately created... This cycle continues until all promises are created and executed.

There are many libraries on npm that implement this function. I personally think that the tiny-async-pool library is better because it directly uses native Promise to implement this function, while most other libraries re-implement promises. The core code is as follows:

async function asyncPool(poolLimit, array, iteratorFn) {
  const ret = []; // used to store all promise instances const executing = []; // used to store the currently executing promise
  for (const item of array) {
    const p = Promise.resolve(iteratorFn(item)); // To prevent the callback function from returning something other than promise, wrap it with Promise.resolve ret.push(p);
    if (poolLimit <= array.length) {
      // In the then callback, when the promise status becomes fulfilled, delete it from the executing promise list executing const e = p.then(() => executing.splice(executing.indexOf(e), 1));
      executing.push(e);
      if (executing.length >= poolLimit) {
        // Once the number of promise lists being executed is equal to the limit, use Promise.race to wait for a promise state to change.
        // After the state changes, the callback of then will be executed, and the promise will be deleted from executing.
        // Then enter the next for loop and generate a new promise to supplement await Promise.race(executing);
      }
    }
  }
  return Promise.all(ret);
}

The test code is as follows:

const timeout = (i) => {
  console.log('start', i);
  return new Promise((resolve) => setTimeout(() => {
    resolve(i);
    console.log('end', i);
  }, i));
};

(async () => {
    const res = await asyncPool(2, [1000, 5000, 3000, 2000], timeout);
    console.log(res);
  })();

The core idea of ​​the code is:

  • First initialize limit promise instances and put them in the executing array
  • Use Promise.race to wait for the execution results of these limit promise instances
  • Once the state of a promise changes, it is removed from executing, and then the loop is executed to generate a new promise and put it into executing.
  • Repeat steps 2 and 3 until all promises are executed.
  • Finally, use Promise.all to return the execution results of all promise instances

This is the end of this article about the method of controlling the number of concurrent calls in js Promise. For more relevant content about js Promise concurrent control, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of Promises in JavaScript
  • Front-end JavaScript Promise
  • JavaScript uses promise to handle multiple repeated requests
  • In-depth understanding of JS asynchronous programming-Promise
  • A Deep Dive into JavaScript Promises

<<:  mysql root user cannot be authorized and solve the problem of navicat remote authorization prompt 1044

>>:  How to solve the problem of Ubuntu 18.04 looping login/stuck on the boot interface/unable to enter the graphical interface

Recommend

Web Design: When the Title Cannot Be Displayed Completely

<br />I just saw the newly revamped ChinaUI....

Regarding the Chinese garbled characters in a href parameter transfer

When href is needed to pass parameters, and the p...

Example of how to change the domestic source in Ubuntu 18.04

Ubuntu's own source is from China, so the dow...

How to use Vue to implement CSS transitions and animations

Table of contents 1. The difference between trans...

Vue recursively implements three-level menu

This article example shares the specific code of ...

How to install git on linux

1. Introduction Git is a free, open source distri...

How to implement Linux automatic shutdown when the battery is low

Preface The electricity in my residence has been ...

A brief analysis of MySQL locks and transactions

MySQL itself was developed based on the file syst...

WeChat Mini Program Lottery Number Generator

This article shares the specific code of the WeCh...

XHTML Tutorial: The Difference Between Transitional and Strict

In fact, XHTML 1.0 is divided into two types (thr...

How to implement second-level scheduled tasks with Linux Crontab Shell script

1. Write Shell script crontab.sh #!/bin/bash step...

How to use dl(dt,dd), ul(li), ol(li) in HTML

HTML <dl> Tag #Definition and Usage The <...

A brief understanding of the difference between MySQL union all and union

Union is a union operation on the data, excluding...

Detailed process record of Vue2 initiating requests using Axios

Table of contents Preface Axios installation and ...