2621. Sleep
Problem Description
The problem requires the creation of an asynchronous function in TypeScript that simulates a sleep or delay for a specified number of milliseconds given by the input parameter 'millis'. The 'millis' is a positive integer representing the time to pause execution of further code. Upon completing the specified pause duration, the function should be able to resume operation although it doesn't need to return any specific value or perform any particular action after the wait is over. The execution should move on, and that is the only requirement.
Intuition
The solution is straightforward due to the nature of JavaScript and TypeScript's handling of asynchronous operations via the Promises API and the built-in setTimeout
function.
setTimeout
is used to delay the execution of a function by a certain number of milliseconds. It is a non-blocking operation, meaning it allows the JavaScript runtime to continue executing other tasks in the event loop while waiting for the timeout to complete.
By wrapping setTimeout
in a Promise, we are creating a promise that will resolve after a set amount of time, thus introducing a pause or sleep effect. This can be done by passing a resolve function r
to the promise constructor, and then passing that resolve function to setTimeout
. The setTimeout
function calls r
after the specified millis
, signaling to the Promise that it is complete. Since we do not care about the value with which the promise resolves, r
can be called with no arguments.
When we call the sleep
function with await
in an async
function or use .then()
after its invocation, the JavaScript runtime will halt the execution of that function, thus effectively "sleeping", until the set amount of time has passed.
The simplicity of this solution makes it an elegant and widely used approach to introduce a deliberate pause in asynchronous execution without blocking the JavaScript event loop.
Solution Approach
The solution takes advantage of the JavaScript event loop and the Promise object to effectively pause execution asynchronously. There are no complex algorithms, data structures, or patterns needed, as the solution leverages existing JavaScript/TypeScript functionalities to accomplish the 'sleep' behavior.
Here's a step-by-step explanation of how the provided solution accomplishes the delay:
-
An asynchronous function
sleep
is declared that takes a single parameter,millis
, which is a number. This function returns a Promise that resolves tovoid
, since the function does not need to return a value once the delay is complete. -
Inside the function, a new Promise is constructed. The constructor of the Promise takes an executor function, which has the resolve function
r
as an argument. -
Within the executor function, we then call
setTimeout
. This is a built-in function that schedules another function to be run after a given number of milliseconds. In this case, our scheduled function is simply the resolve functionr
, which will be called aftermillis
milliseconds. -
By calling the resolve function
r
after the delay provided bysetTimeout
, we tell the Promise that it's okay to continue with the next tasks. Since there's no need for a specific resolve value,r
is called without any arguments. -
When the
sleep
function is used, the caller should eitherawait
it (if within anasync
function) or attach a.then()
method to handle the code that should run after the delay. The event loop is not blocked during this delay, allowing other asynchronous operations to continue. -
Thus, once the set time has elapsed, the function within setTimeout (in this case, the resolve function
r
) is added to the call stack and, if the call stack is clear, is executed, resolving the promise and effectively "waking" the function out of sleep.
No data structures are used in this solution. The asynchronous nature of the Promise, along with the setTimeout
function, provide all the required functionality. This pattern of using setTimeout
within a Promise is a common approach to introduce asynchronous delays in JavaScript and TypeScript codebases.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's say you want to create a simple application that sends a "hello" message to the console, waits for 2 seconds, and then sends a "world" message. Here's a step-by-step walkthrough of how you might use the sleep function to achieve this:
-
Start by declaring an
async
function namedgreet
where thesleep
function will be used. This is your main function. -
Inside the
greet
function, first output "hello" to the console usingconsole.log("hello")
. -
Directly after printing "hello", call the
sleep
function with 2000 milliseconds as the argument to create a 2-second delay. This is written asawait sleep(2000);
. -
After the
sleep
function call, write anotherconsole.log()
statement to output "world" to the console. -
Finally, call the
greet
function to run the complete sequence.
Here's how the code might look given the provided solution approach:
// Declaration of the sleep function
async function sleep(millis: number): Promise<void> {
return new Promise(r => setTimeout(r, millis));
}
// Declaration of the async function that uses sleep
async function greet() {
console.log("hello"); // Step 2: Output "hello"
await sleep(2000); // Step 3: Wait for 2 seconds
console.log("world"); // Step 4: Output "world" after the wait
}
// Execute the function
greet();
When you run this code, you'll see "hello" printed to the console instantly. The program will then pause for 2 seconds, after which "world" will be printed to the console. This demonstrates the non-blocking behavior of the sleep function, as it allows the "hello" message to be processed while the event loop handles other tasks during the 2-second wait before "world" is printed out.
Solution Implementation
1import asyncio
2
3# This function creates a coroutine that completes after a specified number of milliseconds.
4# It uses the asyncio.sleep function internally to delay completion.
5#
6# @param millis: The number of milliseconds to wait before completing.
7# @return: A coroutine that completes after the specified delay.
8
9async def sleep(millis: int) -> None:
10 await asyncio.sleep(millis / 1000) # asyncio.sleep expects seconds, so convert milliseconds to seconds.
11
12# Example usage of the sleep function. It logs the elapsed time (in milliseconds) to the console
13# after the sleep coroutine delay has completed.
14#
15# Usage:
16# asyncio.run(main())
17
18async def main():
19 # Initialize a variable to track the start time.
20 start_time = asyncio.get_event_loop().time() * 1000 # start_time is set in milliseconds
21
22 # Call the sleep coroutine with a delay of 100 milliseconds.
23 await sleep(100)
24
25 # Calculate the elapsed time by subtracting the start time from the current time.
26 elapsed_time = asyncio.get_event_loop().time() * 1000 - start_time # Convert loop time to milliseconds
27
28 # Log the elapsed time to the console.
29 print(elapsed_time) # This will print a value close to 100.
30
31# Run the main function if this script is executed
32if __name__ == '__main__':
33 asyncio.run(main())
34
1import java.util.concurrent.CompletableFuture;
2import java.util.concurrent.TimeUnit;
3
4// This class contains methods for asynchronous operations.
5public class AsyncHelper {
6
7 /**
8 * This method creates a CompletableFuture that completes after a specified number of milliseconds.
9 * It uses the scheduled executor internally to delay the completion of the CompletableFuture.
10 *
11 * @param millis The number of milliseconds to wait before completing the CompletableFuture.
12 * @return A CompletableFuture that completes after the specified delay.
13 */
14 public CompletableFuture<Void> sleep(long millis) {
15 return CompletableFuture.runAsync(() -> {
16 try {
17 TimeUnit.MILLISECONDS.sleep(millis);
18 } catch (InterruptedException e) {
19 Thread.currentThread().interrupt();
20 }
21 });
22 }
23}
24
25// The main class to run the example usage.
26public class SleepExample {
27
28 public static void main(String[] args) {
29 // Create an instance of AsyncHelper to use the sleep method.
30 AsyncHelper asyncHelper = new AsyncHelper();
31
32 // Initialize a variable to track the start time.
33 long startTime = System.currentTimeMillis();
34
35 // Call the sleep method with a delay of 100 milliseconds.
36 asyncHelper.sleep(100).thenRun(() -> {
37 // Calculate the elapsed time by subtracting the start time from the current time.
38 long elapsedTime = System.currentTimeMillis() - startTime;
39
40 // Log the elapsed time to the console.
41 System.out.println(elapsedTime); // This will print a value close to 100.
42 });
43 }
44}
45
1#include <iostream>
2#include <chrono>
3#include <thread>
4
5// This function pauses execution for a specified number of milliseconds.
6//
7// @param millis The number of milliseconds to wait before resuming execution.
8void sleep(int millis) {
9 std::this_thread::sleep_for(std::chrono::milliseconds(millis));
10}
11
12// Example usage of the sleep function. It logs the elapsed time (in milliseconds) to the console
13// after the sleep function delay has completed.
14int main() {
15 // Initialize a variable to track the start time.
16 auto start_time = std::chrono::high_resolution_clock::now();
17
18 // Call the sleep function with a delay of 100 milliseconds.
19 sleep(100);
20
21 // Calculate the elapsed time by subtracting the start time from the current time.
22 auto end_time = std::chrono::high_resolution_clock::now();
23 auto elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count();
24
25 // Log the elapsed time to the console.
26 std::cout << elapsed_time << std::endl; // This will print a value close to 100.
27
28 return 0;
29}
30
1// This function creates a Promise that resolves after a specified number of milliseconds.
2// It uses the setTimeout function internally to delay the resolution of the Promise.
3//
4// @param millis The number of milliseconds to wait before resolving the Promise.
5// @returns A promise that resolves after the specified delay.
6async function sleep(millis: number): Promise<void> {
7 return new Promise(resolve => setTimeout(resolve, millis));
8}
9
10// Example usage of the sleep function. It logs the elapsed time (in milliseconds) to the console
11// after the sleep function delay has completed.
12//
13// Usage:
14// let elapsedTime = Date.now();
15// sleep(100).then(() => console.log(Date.now() - elapsedTime)); // Prints approximately 100
16
17// Initialize a variable to track the start time.
18let startTime: number = Date.now();
19
20// Call the sleep function with a delay of 100 milliseconds.
21sleep(100).then(() => {
22 // Calculate the elapsed time by subtracting the start time from the current time.
23 let elapsedTime: number = Date.now() - startTime;
24
25 // Log the elapsed time to the console.
26 console.log(elapsedTime); // This will print a value close to 100.
27});
28
Time and Space Complexity
Time Complexity: The time complexity of the sleep
function is O(1)
. This is because scheduling a timeout using setTimeout
is an API call that enqueues a callback to be executed after a minimum delay. The complexity of the JavaScript code itself is constant, regardless of the size of millis
.
Space Complexity: The space complexity of the sleep
function is also O(1)
. The function creates a new Promise and a single timer internally, which use a constant amount of space. No additional space that grows with the input size is used.
What is an advantages of top-down dynamic programming vs bottom-up dynamic programming?
Recommended Readings
LeetCode Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way we
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!