Problem Description
Wrap an asynchronous function fn so that it either resolves with its result if it completes within t milliseconds or rejects with the string "Time Limit Exceeded" if it takes longer than t milliseconds to complete. The returned function should forward any arguments provided to fn.
Key Insights
- Use a timeout mechanism (e.g. Promise.race in JavaScript) to compete between the asynchronous task and a timer.
- The timer should reject after t milliseconds with the provided error message.
- If fn throws or rejects before timeout, propagate that error immediately.
- Make sure to forward arguments correctly to fn.
Space and Time Complexity
Time Complexity: O(1) per function call since the overhead is just starting an extra timer. Space Complexity: O(1) aside from the asynchronous call stack.
Solution
We create a wrapper function that returns a new function. When this new function is invoked, it simultaneously starts two asynchronous operations:
- The original function call with all its arguments.
- A timer that triggers a rejection after t milliseconds.
Using a race mechanism (such as Promise.race in JavaScript), whichever of these operations completes first determines the final outcome. Similar ideas are used in Python with asyncio.wait_for, in C++ with std::future and std::thread, and in Java with CompletableFuture and a scheduled executor. The main trick is to correctly cancel or ignore the other operation once one completes and to ensure proper propagation of errors.