# Complex Promise Problems

Before we start incase you are a complete new-bie in the JS world and want to know basics of promiese. There is no better place than [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) docs to do that.

for ease, we can use the below fucntion which generates Bulk Promises.

```javascript
const makeArrayOfPromises = (count)=>{
    const promises = []
    
    for(let i = 1;  i<=count; i++){
    promises.push(
        new Promise((resolve, reject)=>{
        setTimeout(()=>{
           Math.random()>0.6 ? resolve("success") :reject("error")
        }, 100*i)
    })
        )}
    return promises;
      
}
```

Starting with one of most common ones

1. Implement Polyfil for `Promise.all`
    
    ```javascript
    const myPromiseAll = async (promises) => {
        return new Promise((resolve, reject) => {
            const responses = []
            promises.map((each, idx) => {
                each.then((res) => {
                    responses[idx] = res
                    if (responses.length === promises.length) resolve(responses)
                }).catch((err) => {
                    console.error(`Promise ${i + 1} failed with`, err);
                    reject(err)
    
                })
            })
        })
    
    }
    
    myPromiseAll(promises).then(res => console.log(res)).catch(err => console.error(err))
    ```
    
2. Implmenet a Promise batcher that take N promsiese and executes then sequentially
    
    ```javascript
    const runPromisesInBatches = async (promises, batch) => {
        const results = []
        while (promises.length > 0) {
            const result = await Promise.allSettled(promises.slice(0, batch))
            results.push(result)
            promises = promises.slice(10)
    
        }
        return results
    }
    ```
    
3. Implement a promise queue where at any given time N promises are active
    
    ```bash
    
    function promiseQueue(tasks, concurrencyLimit) {
      let index = 0;
      let active = 0;
      const results = [];
    
      return new Promise((resolve, reject) => {
        const next = () => {
          if (index === tasks.length && active === 0) {
            resolve(results);
            return;
          }
    
          while (active < concurrencyLimit && index < tasks.length) {
              
              
            const currentIndex = index++;
            const task = tasks[currentIndex];
            active++;
    
            
             task
              .then((result) => {
                results[currentIndex] = result;
                active--;
                next(); // Start next task
              })
              .catch((err) => {
                reject(err); // Stop everything on first error
              });
          }
          console.log(results)
        };
    
        next(); // Start the first batch
      });
    }
    ```
    
4. MapLimit
    
    Implement a mapLimit function that is similar to the [`Array.map`](http://Array.map)`()` which returns a promise that resolves on the list of output by mapping each input through an asynchronous iteratee function or rejects it if any error occurs. It also accepts a limit to decide how many operations can occur at a time.
    
    The asynchronous iteratee function will accept a input and a callback. The callback function will be called when the input is finished processing, the first argument of the callback will be the error flag and the second will be the result
    
    [https://learnersbucket.com/examples/interview/implement-maplimit-async-function/](https://learnersbucket.com/examples/interview/implement-maplimit-async-function/)
