Hone logo
Hone
Problems

Implementing Promise.all in JavaScript

The Promise.all method is a fundamental part of asynchronous JavaScript, allowing you to wait for multiple promises to resolve before proceeding. This challenge asks you to implement your own version of Promise.all, demonstrating a deeper understanding of promises and asynchronous operations. Successfully implementing Promise.all is crucial for managing concurrent tasks and ensuring data dependencies are met.

Problem Description

You are tasked with creating a function PromiseAll(promises) that mimics the behavior of the native Promise.all method. The function should accept an array of promises as input and return a new promise. This new promise should resolve with an array of the resolved values of the input promises, in the same order as the input array. If any of the input promises reject, the returned promise should immediately reject with the reason of the first rejected promise.

Key Requirements:

  • Resolution: The returned promise should resolve only after all input promises have resolved.
  • Order Preservation: The resolved array should maintain the original order of the input promises.
  • Rejection: If any input promise rejects, the returned promise should reject immediately with the rejection reason.
  • Empty Input: If the input array is empty, the returned promise should resolve immediately with an empty array.
  • Non-Promise Values: The input array can contain non-promise values. These values should be wrapped in a resolved promise before being included in the final resolved array.

Expected Behavior:

The function should handle both successful resolutions and rejections gracefully, adhering to the principles of promise resolution and rejection. It should also correctly manage edge cases like an empty input array and non-promise values within the input array.

Edge Cases to Consider:

  • Empty input array.
  • Input array containing non-promise values (e.g., numbers, strings, objects).
  • Promises that resolve or reject very quickly.
  • Promises that never resolve or reject (though this is generally considered a programming error, your implementation should ideally not hang indefinitely).

Examples

Example 1:

Input: [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)]
Output: [1, 2, 3]
Explanation: All three promises resolve successfully, and the returned promise resolves with an array containing their resolved values in the original order.

Example 2:

Input: [Promise.resolve(1), Promise.reject('Error'), Promise.resolve(3)]
Output: 'Error'
Explanation: The second promise rejects with 'Error'. The returned promise immediately rejects with the same reason, and the other promises are effectively ignored.

Example 3:

Input: [1, Promise.resolve(2), 3]
Output: [1, 2, 3]
Explanation: The non-promise values (1 and 3) are treated as already resolved promises with their respective values.

Example 4:

Input: []
Output: []
Explanation: The input array is empty. The returned promise resolves immediately with an empty array.

Constraints

  • The input promises will always be an array.
  • The array may contain a mix of promises and non-promise values.
  • The function should not modify the original input array.
  • The function should be implemented using standard JavaScript and promises.
  • The function should handle a maximum of 1000 promises in the input array. (Performance is not the primary focus, but avoid excessively inefficient solutions).

Notes

  • Consider using Promise.allSettled as a reference for handling both resolved and rejected promises, but do not directly use it in your implementation. The goal is to understand the underlying logic.
  • Think about how to track the progress of each promise and how to handle rejections efficiently.
  • Remember to handle the edge case of an empty input array correctly.
  • Non-promise values should be treated as already resolved promises. You can achieve this by wrapping them in Promise.resolve().
Loading editor...
javascript