
Problem Statement
In the provided problem, you are given an array named functions
, where each element is a function that returns a promise (fnPromise
). These promises can either resolve or reject. On resolution, each promise is expected to result in an object with properties status: "fulfilled"
and value: the resolved value
. Conversely, if a promise is rejected, it should produce an object with properties status: "rejected"
and reason: a string describing the reason for rejection
.
Your task is to create a promise promise
that when resolved, contains an array of these objects, each representing the outcome of the corresponding promise in the functions
array, preserving the original order.
The challenge requires implementing this behavior manually, without using the Promise.allSettled()
method, which would typically automate much of this process.
Examples
Example 1
Input:
functions = [ () => new Promise(resolve => setTimeout(() => resolve(15), 100)) ]
Output:
{"t":100,"values":[{"status":"fulfilled","value":15}]}
Explanation:
The promise resolves in 100ms. The single function resolves successfully, so the result is an array with one object: [{"status":"fulfilled","value":15}]
Example 2
Input:
functions = [ () => new Promise(resolve => setTimeout(() => resolve(20), 100)), () => new Promise(resolve => setTimeout(() => resolve(15), 100)) ]
Output:
{ "t":100, "values": [ {"status":"fulfilled","value":20}, {"status":"fulfilled","value":15} ] }
Explanation:
Both functions resolve after 100ms, so the output contains two fulfilled entries in the same order: [{"status":"fulfilled","value":20}, {"status":"fulfilled","value":15}]
Example 3
Input:
functions = [ () => new Promise(resolve => setTimeout(() => resolve(30), 200)), () => new Promise((resolve, reject) => setTimeout(() => reject("Error"), 100)) ]
Output:
{ "t":200, "values": [ {"status":"fulfilled","value":30}, {"status":"rejected","reason":"Error"} ] }
Explanation:
The second promise rejects in 100ms and the first fulfills in 200ms. Final result preserves order: [{"status":"fulfilled","value":30}, {"status":"rejected","reason":"Error"}]
Constraints
1 <= functions.length <= 10
Approach and Intuition
To solve this problem, we manually simulate the behavior of Promise.allSettled()
:
Create an array to store results:
- Allocate a fixed-size array (
results
) equal to the number of functions. - This helps maintain the order of output, regardless of the resolution order.
- Allocate a fixed-size array (
Initialize a counter:
- Count how many promises have settled (resolved or rejected).
- Once all have settled, resolve the final outer promise with the
results
array.
Loop through each function and invoke:
- For each
functions[i]()
, attach a.then()
handler to store{ status: "fulfilled", value }
inresults[i]
. - Also attach a
.catch()
handler to store{ status: "rejected", reason }
inresults[i]
.
- For each
Check for completion:
- After each result (fulfilled or rejected), increment the
settledCount
. - If all functions have settled, resolve the final promise with the
results
array.
- After each result (fulfilled or rejected), increment the
This manual tracking approach ensures:
- Order is preserved.
- Both resolutions and rejections are handled.
- Output mimics
Promise.allSettled()
without using it.
Solutions
- JavaScript
var allFuncsSettle = function(promises) {
return new Promise(done => {
if(promises.length === 0) {
done([]);
return;
}
const outcomes = new Array(promises.length).fill(null);
let completedCount = 0;
const finalize = (result, idx) => {
outcomes[idx] = result;
completedCount++;
if(completedCount === promises.length) done(outcomes);
};
promises.forEach((promiseFunc, idx) => {
promiseFunc().then(resultValue => {
finalize({status: 'fulfilled', value: resultValue}, idx);
}, error => {
finalize({status: 'rejected', reason: error}, idx);
});
});
});
};
The JavaScript function allFuncsSettle
efficiently handles the execution of an array of promises, ensuring each promise's result is individually tracked and stored. This function is particularly useful when you need to manage multiple asynchronous operations and care about the resolved or rejected status of each.
Here's a breakdown of how this function works:
- The function
allFuncsSettle
receives an array of promises. - It returns a new Promise that completes when all the promises in the input array have settled (either resolved or rejected).
- Inside, if the array is empty, it immediately resolves with an empty array.
- An
outcomes
array is initialized to store the results of each promise at the same index they occurred in the input array. - Counters like
completedCount
track how many promises have been processed. - The
finalize
helper function is integral to the process. It updates theoutcomes
array with the result of each promise (success or error) and checks if all promises have been settled. Once all are settled, the main Promise resolves with theoutcomes
array.
This achieves the goal of running multiple promises in parallel and retrieving their results as they resolve or reject, unlike methods like Promise.all
which requires all promises to succeed to return a result. This function can be handy in situations where each task's independent completion is critical regardless of the others' outcomes.
No comments yet.