# Mastering Concurrency Implementation in JavaScript

🚀 Concurrency Implementation in `JavaScript`

![](https://miro.medium.com/v2/resize:fit:1155/1*wbnKyc6PE6w02Joe7eZMQw.jpeg align="left")

*Photo by* [*Nicolas Hoizey*](https://unsplash.com/@nhoizey?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash) *on* [*Unsplash*](https://unsplash.com/photos/woman-running-competition-Lno6-CxVXgo?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash)  
<mark>Hello everyone, I am </mark> *<mark>Biao Zhu</mark>*<mark>.<br>I hope you enjoy reading this article.</mark>

[Today, let’s learn about concurr](https://medium.com/illumination/mastering-concurrency-implementation-in-javascript-4a93b46cad6e?sk=b0e01d18e650b3fc498b9b3107d5f7cc)ency control in JavaScript. In your everyday development, you might encounter scenarios where concurrency control is necessary, such as controlling the concurrency of requests. So, how can we implement concurrency control in JavaScript? But before answering this question, let’s briefly introduce concurrency control.

> \*\*\*01.What is concurrency control？\*\*\**🤔*

<mark>Assume there are 5 tasks to be executed. We want to limit the number of tasks executed simultaneously to 2, meaning only a maximum of 2 tasks can be executed concurrently. When any one task in the list of tasks being executed is completed, the program will automatically fetch a new task from the list of pending tasks and add it to the list of tasks being executed. To help everyone understand the process more intuitively, Biao specially drew the following 3 diagrams:</mark>

## **stage1**

![](https://miro.medium.com/v2/resize:fit:1155/1*IVc69MGaqgy-ECMTHjvJZA.png align="left")

Images created by the author

## **stage2**

![](https://miro.medium.com/v2/resize:fit:1155/1*PLYK4pKsDIRiiVHYzcFT0w.png align="left")

Images created by the author

## **stage3**

![](https://miro.medium.com/v2/resize:fit:1155/1*2nhkl9UIgPYZYU1T7-m4yg.png align="left")

Images created by the author

> \*\*\*02.How to implement concurrency control？\*\*\**🧐*

<mark>After introducing concurrency control, I will demonstrate the specific implementation of asynchronous task concurrency control using the </mark> [`async-pool`](https://github.com/rxaviers/async-pool) <mark> library on </mark> *<mark>GitHub</mark>*<mark>.</mark>

***2.1 The usage of asyncPool*** 😎

```plaintext
const timeout = i => new Promise(resolve => 
    setTimeout(() => resolve(i), i)
);
await asyncPool(2, [1000, 5000, 3000, 2000], timeout);
```

In the above code, we utilize the *‘asyncPool’* function provided by the `asyncPool` library to implement concurrency control for asynchronous tasks. The signature of the `asyncPool` the function is as follows :

```plaintext
function asyncPool(poolLimit, array, iteratorFn){ ... }
```

<mark>The function takes 3 parameters:</mark>

* `poolLimit` (*number type*): Indicates the concurrency limit.
    
* `array` (*array typ*e): Represents the array of tasks.
    
* `iteratorFn` (*function type*): Represents the iterator function used to process each task item, which returns a Promise object or an asynchronous function.
    

<mark>For the example above, after using the </mark> `asyncPool` <mark> function, the corresponding execution process is as follows:</mark>

```plaintext
const timeout = i => new Promise(resolve => setTimeout(() => resolve(i), i));
await asyncPool(2, [1000, 5000, 3000, 2000], timeout);
// Call iterator (i = 1000)
// Call iterator (i = 5000)
// Pool limit of 2 reached, wait for the quicker one to complete...
// 1000 finishes
// Call iterator (i = 3000)
// Pool limit of 2 reached, wait for the quicker one to complete...
// 3000 finishes
// Call iterator (i = 2000)
// Itaration is complete, wait until running ones complete...
// 5000 finishes
// 2000 finishes
// Resolves, results are passed in given array order `[1000, 5000, 3000, 2000]`.
```

By observing the comments above, we can roughly understand the control flow inside the `asyncPool` function. Now let’s analyze the ES7 implementation of the `asyncPool` function.

***<mark>2.2 asyncPool ES7 </mark>*** <mark>🫢</mark>

```plaintext
async function asyncPool(poolLimit, array, iteratorFn) {
  const ret = []; //  Store all asynchronous tasks
  const executing = []; //  Store currently executing asynchronous tasks
  for (const item of array) {
    //  Call the iteratorFn function to create asynchronous tasks
    const p = Promise.resolve().then(() => iteratorFn(item, array));
    ret.push(p); // Save the new asynchronous task
    //  When poolLimit is less than or equal to the total number of 
    //  tasks, perform concurrency control.
    if (poolLimit <= array.length) {
      // After the task is completed, 
      // remove the completed task from the array of executing tasks.
      const e = p.then(() => executing.splice(executing.indexOf(e), 1));
      executing.push(e); // Save the executing asynchronous task.
      if (executing.length >= poolLimit) {
        // Wait for the fastest task to complete execution.
        await Promise.race(executing); 
      }
    }
  }
  return Promise.all(ret);
}
```

In the above code, the characteristics of `Promise.all` and `Promise.race` functions are fully utilized, combined with the `async await` feature provided in ES7, to ultimately achieve concurrency control. By using the statement await `await Promise.race(executing);`, we wait for the fastest task in the **list of executing tasks** to complete before proceeding to the next iteration.

The `async-pool` library also provides an **ES6** implementation approach, which interested individuals can explore and learn more about.

**Conclusion** 🚀

<mark>This article meticulously analyzes the core code of </mark> `async-pool` <mark> to help readers better understand the specific implementation of asynchronous task concurrency control using </mark> `async-pool`<mark>.</mark>  
  
*Thank you for reading until the end. Before you go:*

* *Please consider following me 👏 and you can* [***subscribe***](https://zhubiao.medium.com/) *to my medium.*
    
* *I am looking forward to your* ***reply*** *and* ***communicating*** *with you!*💬
