Complete Understanding
Today , I faced an interesting challenge: I had to run multiple async functions in parallel and get all their results in the same order as the input. At first,
Today , I faced an interesting challenge: I had to run multiple async functions in parallel and get all their results in the same order as the input. At first, I thought it was a straightforward task. "How hard could it be?" I asked myself. I quickly wrote some code, ran it, and… it didn’t work! 😅 The results were either incomplete or empty. That’s when my real learning journey began.

---

#### 🚧 My First Attempt (Where I Got Stuck)

Here’s what I tried at the start: I used a `forEach` loop to run all the async functions. My plan was to collect their results in an array and then resolve the promise when the loop finished. The code looked like this:  

[Leetcode Problem Link](https://leetcode.com/problems/execute-asynchronous-functions-in-parallel/)

```javascript
var promiseAll = function (functions) {
    return new Promise((resolve, reject) => {
        const results = []; // Store the results
        functions.forEach(fn => {
            fn().then(value => results.push(value)).catch(reject);
        });
        resolve(results); // Resolve after the loop
    });
};
```

I thought this would work, but when I ran it, the results were wrong. Sometimes the array was empty or incomplete. I felt stuck and couldn’t figure out why.

---

#### 🤔 What I Learned About Promises and Loops

To understand the issue, I read about how promises and loops work together. That’s when I learned these key points:  

1. **`forEach` is synchronous:** The loop finishes very quickly and doesn’t wait for promises to resolve.  
2. **Promises are asynchronous:** They keep running in the background and resolve only when their work is done.  
3. **Timing matters:** I was calling `resolve(results)` too early, before the promises finished.

Here’s how the issue looked in my head:

```
🌀 forEach: Loop runs fast 🏃‍♂️
  ↪️ Calls function 1 🤖 (Promise starts)
  ↪️ Calls function 2 🤖 (Promise starts)
  ↪️ Calls function 3 🤖 (Promise starts)
🚩 Reaches resolve(results) ⏱️ BEFORE promises finish!
```

---

#### 🛠️ Fixing the Problem: Track Progress and Order

To fix my code, I needed to:  
1. Wait until all promises were done.  
2. Keep track of their resolved values in the correct order.  
3. Stop everything if one promise failed.  

Here’s the updated code:  

```javascript
var promiseAll = function (functions) {
    return new Promise((resolve, reject) => {
        const results = []; // Store results in order
        let completed = 0;  // Track completed promises

        functions.forEach((fn, index) => {
            fn()
                .then(value => {
                    results[index] = value; // Store value at the right position
                    completed++;
                    if (completed === functions.length) {
                        resolve(results); // Resolve when all are done
                    }
                })
                .catch(error => {
                    reject(error); // Reject immediately on error
                });
        });
    });
};
```

Now, my code:  
1. Used a counter (`completed`) to track how many promises had finished.  
2. Stored results at the correct index (`results[index] = value`) to preserve order.  
3. Resolved only when all promises were done (`completed === functions.length`).  

---

#### 📊 Diagram of How It Works

Here’s how the fixed solution works:

```
🔄 forEach: Loop calls functions
  ↪️ Function 1 🤖 (Promise starts) ➡️ Resolves with 5 ✅
  ↪️ Function 2 🤖 (Promise starts) ➡️ Resolves with 10 ✅
  ↪️ Function 3 🤖 (Promise starts) ➡️ Resolves with 15 ✅
🧮 Track completed promises: 1️⃣ 2️⃣ 3️⃣
🎉 Resolve when all are done: [5, 10, 15]
```

---

#### 🎉 Testing the Code

Here’s how I tested the solution:

```javascript
const functions = [
    () => new Promise(resolve => setTimeout(() => resolve(1), 200)),
    () => new Promise(resolve => setTimeout(() => resolve(2), 100)),
    () => new Promise(resolve => setTimeout(() => resolve(3), 300))
];

promiseAll(functions).then(console.log).catch(console.error);
// Output: [1, 2, 3]

const functionsWithError = [
    () => new Promise(resolve => setTimeout(() => resolve(1), 200)),
    () => new Promise((_, reject) => setTimeout(() => reject("Error"), 100))
];

promiseAll(functionsWithError).then(console.log).catch(console.error);
// Output: "Error"
```

---

#### 🧠 What I Learned

1. **Loops and promises behave differently:** Loops like `forEach` are fast, but promises run asynchronously in the background.  
2. **Track progress:** A counter is essential to ensure all tasks are done before resolving.  
3. **Preserve order:** Even if promises finish at different times, store their results in the correct order.  
4. **Error handling:** Stop everything immediately if one promise fails.

---

#### 🌟 Final Thoughts

At first, this challenge felt frustrating, but it turned out to be a great learning experience. I now understand promises better and feel more confident handling async code. It’s a reminder that sometimes, the best lessons come from the hardest problems!
['JavaScript']