Given an array of asynchronous functions functions, return a new promise promise. Each function in the array accepts no arguments and returns a promise. All the promises should be executed in parallel.
promise resolves:
functions were resolved successfully in parallel. The resolved value of promise should be an array of all the resolved values of promises in the same order as they were in the functions. The promise should resolve when all the asynchronous functions in the array have completed execution in parallel.promise rejects:
functions were rejected. promise should also reject with the reason of the first rejection.Please solve it without using the built-in Promise.all function.
Example 1:
Input: functions = [
() => new Promise(resolve => setTimeout(() => resolve(5), 200))
]
Output: {"t": 200, "resolved": [5]}
Explanation:
promiseAll(functions).then(console.log); // [5]
The single function was resolved at 200ms with a value of 5.
Example 2:
Input: functions = [
() => new Promise(resolve => setTimeout(() => resolve(1), 200)),
() => new Promise((resolve, reject) => setTimeout(() => reject("Error"), 100))
]
Output: {"t": 100, "rejected": "Error"}
Explanation: Since one of the promises rejected, the returned promise also rejected with the same error at the same time.
Example 3:
Input: functions = [
() => new Promise(resolve => setTimeout(() => resolve(4), 50)),
() => new Promise(resolve => setTimeout(() => resolve(10), 150)),
() => new Promise(resolve => setTimeout(() => resolve(16), 100))
]
Output: {"t": 150, "resolved": [4, 10, 16]}
Explanation: All the promises resolved with a value. The returned promise resolved when the last promise resolved.
Constraints:
functions is an array of functions that returns promises1 <= functions.length <= 10When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
Imagine you have a group of tasks that can be done at the same time. The most basic way to handle them is to wait for each one, one after the other. It's like doing your chores by finishing one completely before even starting the next.
Here's how the algorithm would work step-by-step:
import asyncio
async def execute_asynchronous_functions_serially(asynchronous_functions):
results = []
# Iterate through each asynchronous function.
for asynchronous_function in asynchronous_functions:
# Wait for the completion of current asynchronous function before proceeding.
result = await asynchronous_function()
# Store the result after its completion.
results.append(result)
return resultsTo run multiple tasks at the same time efficiently, we'll use a way to track when each task finishes. We will start all the tasks at once and then use a 'promise' which is like a placeholder that tells us when each is done, allowing us to know when *all* tasks are complete.
Here's how the algorithm would work step-by-step:
import asyncio
async def execute_async_functions_in_parallel(async_functions):
# Create a list to hold the task objects
tasks = []
for async_function in async_functions:
# Schedule each function to run concurrently
task = asyncio.create_task(async_function())
tasks.append(task)
# Await all tasks to complete and gather the results
# This ensures all functions finish before proceeding
results = await asyncio.gather(*tasks)
return results
async def main():
async def async_function_one():
await asyncio.sleep(1)
return "Function One Result"
async def async_function_two():
await asyncio.sleep(2)
return "Function Two Result"
async def async_function_three():
await asyncio.sleep(0.5)
return "Function Three Result"
async_functions_list = [async_function_one, async_function_two, async_function_three]
# Run the asynchronous functions in parallel
# This call triggers the concurrent execution
results = await execute_async_functions_in_parallel(async_functions_list)
print(results)
if __name__ == "__main__":
# Run the main function using asyncio
asyncio.run(main())| Case | How to Handle |
|---|---|
| Empty array of functions | Return immediately, resolving the promise with an empty array since there's nothing to execute. |
| Array containing null or undefined functions | Filter out null or undefined elements to prevent errors during execution, or throw an error if null/undefined functions are not expected. |
| Functions that throw exceptions | Catch exceptions from individual functions, reject the main promise immediately, and log the error or continue executing other functions depending on requirements. |
| Functions that never resolve or reject (infinite loop) | Implement a timeout mechanism to reject promises that take too long, preventing the entire program from hanging indefinitely. |
| Maximum number of concurrent promises exceeding system limits | Utilize a concurrency limiter (e.g., a semaphore) to control the maximum number of promises running simultaneously. |
| Functions with different return types. | Ensure the return type is compatible or perform necessary type conversions before returning the aggregated results. |
| Functions with dependencies on each other. | This implementation assumes independent functions, and a dependency graph should be supported in a more complex version to execute in the correct order. |
| Large number of functions causing stack overflow if using recursion. | Avoid recursion by using iterative methods like for loops and/or manage the stack using a queue or other iterative approach. |