Delay the Resolution of Each Promise

Updated on 21 May, 2025
Delay the Resolution of Each Promise header image

Problem Statement

In this task, you're provided with an array named functions, where each element is a function that returns a promise—either resolved or rejected after a predetermined duration. Additionally, you receive an integer ms, representing milliseconds. Your goal is to construct a new array of functions. Each function in this new array should still return a promise as before but with an added delay of ms milliseconds.

The primary challenge is to ensure this "delay extension" behavior affects each promise, whether it resolves or rejects, and that the new functions maintain the same operation order as in the original functions array. Implementing this functionality requires carefully incorporating additional asynchronous delays without altering the original promise's outcome (resolved or rejected).

Examples

Example 1

Input:

functions = [
  () => new Promise((resolve) => setTimeout(resolve, 30))
],
ms = 50

Output:

[80]

Explanation:

The promise from the array would have resolved after 30 ms, but it was delayed by 50 ms, thus 30 ms + 50 ms = 80 ms.

Example 2

Input:

functions = [
  () => new Promise((resolve) => setTimeout(resolve, 50)),
  () => new Promise((resolve) => setTimeout(resolve, 80))
],
ms = 70

Output:

[120,150]

Explanation:

The promises from the array would have resolved after 50 ms and 80 ms, but they were delayed by 70 ms, thus 50 ms + 70 ms = 120 ms and 80 ms + 70 ms = 150 ms.

Example 3

Input:

functions = [
  () => new Promise((resolve, reject) => setTimeout(reject, 20)),
  () => new Promise((resolve, reject) => setTimeout(reject, 100))
],
ms = 30

Output: [50,130]

Constraints

  • functions is an array of functions that return promises
  • 10 <= ms <= 500
  • 1 <= functions.length <= 10

Approach and Intuition

To tackle this problem, you can follow these structured steps:

  1. Capture Promise Behavior and Delay: For each function in the functions array, you need to create a new function that continues to return a promise. This promise should encapsulate the behavior of the original promise plus the additional delay of ms milliseconds.

  2. Use of JavaScript Timeout: Each new function will typically utilize setTimeout to implement the delay. Regardless of the original promise resolving or rejecting, the setTimeout can wrap around the original promise handling logic.

  3. Preservation of Original Promise Outcome: It's crucial to maintain the outcome (resolve or reject) of the original promise even with the added delay. Use the promise constructor and ensure to call either resolve() or reject() based on the original promise’s outcome, but after the set timeout period.

    • For a function that resolves a promise after x milliseconds, the new function should effectively resolve the promise after (x + ms) milliseconds.
    • Similarly, if a function rejects a promise in the original array, the corresponding function in the new array should reject the promise but again after an additional delay of ms milliseconds.
  4. Handling Completeness and Errors: Ensure that all possible errors are handled appropriately within your promise logic. This includes potential errors in the original promise execution that need to be delayed similarly.

  5. Testing Each Component: Given the constraints and possible promise behaviors, ensure to test:

    • Multiple promises with varying resolve/reject times in functions.
    • Edge cases for ms (minimum of 10 and maximum of 500 milliseconds).
    • A solitary function in functions as well as the maximum limit of 10 functions.

By following these steps, you introduce a systematic delay to the execution of each promise without affecting their original resolve/reject behaviors, thus meeting the requirement to return a new array of delayed promise-returning functions.

Solutions

  • JavaScript
js
function delayAll(functions, ms) {
  const delayedFuncs = [];

  functions.forEach(func => {
    const delayedPromiseFunc = () => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          func()
            .then(result => {
              resolve(result);
            })
            .catch(error => {
              reject(error);
            });
        }, ms);
      });
    }

    delayedFuncs.push(delayedPromiseFunc);
  });

  return delayedFuncs;
};

The provided JavaScript function, delayAll, takes an array of functions (that return promises) and a delay time in milliseconds (ms). It returns a new array of functions. These functions, when invoked, will return a promise that resolves only after the specified delay, maintaining the resolution or rejection of the original promise.

Follow these steps to understand how delayAll works:

  1. Initialize an empty array, delayedFuncs, to store the delayed functions.
  2. Iterate over the functions array using forEach.
  3. For each function (func), create a new function delayedPromiseFunc.
  4. delayedPromiseFunc returns a new Promise.
  5. Inside the Promise, use setTimeout to delay execution.
  6. After the delay, execute func() and use .then and .catch to handle the resolved result or any errors.
  7. Push delayedPromiseFunc to the delayedFuncs array.
  8. Return delayedFuncs. Each function within this array can be executed to initiate the delayed promise.

This approach ensures each function's promise is only handled after the specified delay, effectively staggering their execution in an asynchronous manner.

Comments

No comments yet.