> For the complete documentation index, see [llms.txt](https://choubey.gitbook.io/javascript-interview-questions/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://choubey.gitbook.io/javascript-interview-questions/question-81.md).

# Question 81

### Question

Describe how to implement a basic Promise polyfill.

### Answer

**Basic Polyfill Implementation:**

```javascript
if (!Promise) {
  window.Promise = function(executor) {
    if (typeof executor !== 'function') {
      throw new TypeError('Executor must be a function');
    }
    let state = 'pending';
    let value;
    let resolveQueue = [];
    let rejectQueue = [];

    const resolve = (v) => {
      if (state === 'pending') {
        value = v;
        state = 'fulfilled';
        processQueue(resolveQueue);
      }
    };

    const reject = (r) => {
      if (state === 'pending') {
        value = r;
        state = 'rejected';
        processQueue(rejectQueue);
      }
    };

    executor(resolve, reject);

    const processQueue = (queue) => {
      while (queue.length > 0) {
        const callback = queue.shift();
        try {
          callback(value);
        } catch (error) {
          // Handle errors appropriately here
        }
      }
    };

    return {
      then: function(onFulfilled, onRejected) {
        if (typeof onFulfilled !== 'function') {
          onFulfilled = value => value; 
        }
        if (typeof onRejected !== 'function') {
          onRejected = error => { throw error };
        }
        return new Promise((resolve, reject) => {
          if (state === 'fulfilled') {
            try {
              resolve(onFulfilled(value)); 
            } catch (error) {
              reject(error);
            }
          } else if (state === 'rejected') {
            try {
              resolve(onRejected(value));
            } catch (error) {
              reject(error);
            }
          } else { 
            resolveQueue.push(() => {
              try {
                resolve(onFulfilled(value));
              } catch (error) {
                reject(error);
              }
            });
            rejectQueue.push(() => {
              try {
                resolve(onRejected(value));
              } catch (error) {
                reject(error);
              }
            }); 
          }
        });
      },
    };
  };
}
```

**Explanation:**

1. **Check for Native Promises:** The `if (!Promise)` block ensures the polyfill is only executed in environments without native Promise support.
2. **Custom `Promise` Constructor:** We create our own `Promise` constructor function, mimicking the behavior of the built-in one.
3. **States (`pending`, `fulfilled`, `rejected`)**: The Promise can exist in these three states to track its execution status.
4. **Queues (`resolveQueue`, `rejectQueue`):** These queues store callbacks that should be executed when the Promise is fulfilled or rejected. This allows us to handle asynchronous operations without blocking the main thread.
5. **`resolve()` and `reject()` Functions**: These functions update the state of the Promise and trigger the execution of callbacks in the corresponding queue.
6. **`then()` Method:** The polyfill's `then()` method accepts two optional callback functions: one for success (`onFulfilled`) and one for failure (`onRejected`). It returns a new Promise, which allows chaining asynchronous operations.

**Important Notes:**

* This is a very basic polyfill. For more comprehensive coverage, consider using existing well-maintained polyfills like the one from core-js:

  ```javascript
  import 'core-js/stable'; // Includes Promises polyfill and other essential features
  ```
