Sleep - Leetcode 2621 - JavaScript 30-Day Challenge

NeetCodeIO · Intermediate ·⚡ Algorithms & Data Structures ·3y ago

Key Takeaways

Solves Leetcode 2621 using JavaScript with a focus on async programming

Full Transcript

hey everyone welcome back and let's write some more neat code today so today let's solve day 11 of the JavaScript Challenge and we have the problem sleep this is probably the most important one yet because we're going to be learning about asynchronous programming which is one of the huge advantages of JavaScript I know I talked a little bit about the disadvantages in the previous videos JavaScript is a little bit unique it has a deep history of a sync programming which contrasts with a language like Java which has a long history as a synchronous blocking language which in today's age with like web programming and apis is a pretty big disadvantage I actually migrated some Java code at Google to non-blocking I know that sounds pretty exciting doesn't it but it just goes to show even places like Google have a lot of blocking Java code which they're definitely not happy about but it's definitely an investment if they want to migrate it getting into today's problem we are given a positive integer Millis and we just want to write in asynchronous function that sleeps for this many seconds and it can resolve to any value this last sentence might get you off guard if you're not familiar with something in JavaScript called promises which are kind of the backbone of modern asynchronous programming in JavaScript and the thing is with JavaScript any asynchronous function will return a promise and Promises will resolve to some value at some point but before we get too deep let me actually show you some promises the most basic example is set time out basically this takes two parameters it takes in for the first parameter a function so I'm going to define a function which maybe is just called hello all it does is maybe console.log hello pretty simple so we pass this function using its name into set timeout we're not calling this function we're passing it in as like a parameter and the second parameter is going to be the number of milliseconds that we want to wait so a thousand milliseconds is one second so set timeout which we're executing here is basically going to wait one second and then console.log hello and I'm actually going to call it twice to illustrate that it is waiting so now let's actually run the code and see what happens we can see we're waiting and both of them printed at the same time you might not have been expecting that and actually neither was I but then I just realized we called both of these almost instantly and then the next line is going to be executed they were both executed pretty quickly but then both of them waited one second and then actually executed the value but let me actually call the second one with two thousand milliseconds and then you'll see that we are going to get that wait time we were expecting so let's rerun this and you see we're waiting one second and then another second we got the second one so it's doing pretty much what we expect so now let's take a look at what promises happen to be a promise is a special object in JavaScript and it can be in three possible States one is the pending state which basically means it hasn't been resolved yet and the second is the resolved State and lastly is the rejected State we'll be going through all of these so don't worry if you don't understand them all quite yet but the best way to show you what a promise is doing is to actually Implement one from scratch well rather construct one from scratch because it's an object we can construct with the new keyword every promise takes in a callback a callback is essentially a function we could pass that function in in line like this or we could Define the function separately down here I think it's a little bit more clear for beginners to define the Callback here so I'm just gonna do exactly that callback and typically the Callback passed in to a promise will have two parameters one is resolve and second is reject you could technically name these whatever you want but I would stick with the convention which is resolve and reject and it's actually not required I believe to pass both of these in but that's just because JavaScript is a weird language usually you should pass both of these in and the idea behind this callback is that we might do some kind of asynchronous operation which is going to take some time to execute I'm not talking about like adding two numbers together technically that takes some time as well I'm talking about doing something much more expensive something like a network call or maybe a disk read like some kind of i o because we know the bottleneck with these types of operations is not in terms of executing code we could be executing JavaScript as fast as we want our CPU could be going blazingly fast it doesn't matter the bottleneck behind a network call is sometimes infrastructure you might be on the other side of the world it doesn't matter what your computer is doing you still have to wait so if you are waiting for some kind of expensive operation what should our code be doing should our code just be sitting idle should we just be doing nothing should the CPU just be wasting CPU Cycles probably not that's the motivation behind making JavaScript an asynchronous and non-blocking language so when you load something like YouTube there's a bunch of asynchronous non-blocking calls being made but that's okay because JavaScript can continue to execute that's not always the case with a language like Java and that's kind of a very important concept to understand this is one of the huge advantages of JavaScript and this is why JavaScript is a powerful language even though it is single threaded because you don't need a thread to wait for a network call or to wait for a disk read these things can be done in parallel even though some JavaScript is still running on the main thread that said the single threaded nature of JavaScript does sometimes limit CPU tasks so if you are doing something super intensive like adding a bunch of numbers together or a lot of computations JavaScript might be a bottleneck in some cases but let's get back to the promise example here suppose we're doing some asynchronous call to mimic that I'm going to call set timeout that's kind of a very easy thing we can do do and let's say the set timeout is just going to do something very simple like console.log hello and it's going to execute after one second now after that executes let's say we want to resolve this promise well if we want to actually wait a thousand milliseconds we should probably call our resolve over here because we're calling the resolve out here this is not necessarily going to weight the 1000 milliseconds so to fix this let's actually take this resolve and move it inside of this Anonymous function here basically this function will execute wait one second and then call resolve and this is the function we pass into our promise and let's assign it to a variable which we're just going to call promise here and remember because of how hoisting Works in JavaScript this function is defined out down here but we can still pass it in up here so now with our promise let me show you how this promise is actually used after this operation is done and the promise has been success fully resolved we can use the then method that belongs to every single promise and the then method takes in a callback which is you know just another function like this one but in our case I'm going to do something more simple I'm going to pass in an anonymous function which is now actually going to console log hello so now what this promise should do is after waiting one second it will resolve and then after one second we will console.log hello let's execute it and see what happens yep it waited about a second maybe a little bit more but we did get what we wanted now there's a second method that belongs to promise which is called catch this one also accepts a callback let's say in this one I'm going to pass in a similar function but instead of logging hello I'm going to say error occurred or rather promise rejected because that's going to be a bit more descriptive now I'm going to change this callback to instead of calling resolve it's going to call the second parameter which usually corresponds to reject regardless of what you name these the name doesn't change anything the second parameter is always the one that corresponds to reject so we take this reject and now we call it here and now which one of these do you think is going to execute well let's find out we waited a second promise dot rejected because rejected was called now this is a pretty contrived example but normally what would actually happen in here is we would execute something usually with a try catch block and we would maybe in the try make some kind of network call or some kind of async operation if it's successful then we call resolve if it is unsuccessful we execute the catch block catching whatever error occurred and then down here we would call reject so then when our callbacks execute we actually know what happened inside of the Callback was it successful or was it unsuccessful and each of these methods actually takes a parameter so for the reject case now if some error occurs Maybe be I want to call reject saying what error occurred or maybe passing some error object but here now I'm gonna say error occurred and up here we do expect the catch to execute I'm just going to get rid of the then because it's actually not required but the catch now this Anonymous function we pass in actually has a parameter that will be provided to it because that's the parameter we passed in to reject so it is an error message and now instead of console logging this string we're going to console log that error message and you'll see this is what ends up being logged after a second well I guess the way this try catch is set up we're not guaranteed that this will execute so I'm going to get rid of this try catch and then move this here now let's run it and you can see yep error occurred and it didn't even wait a second this time because we got rid of the set timeout now what happens if we never call resolve or reject if we just never do anything maybe in here I'm just going to console log something which is great but we never ended up resolving or rejecting This Promise so what would happen and then well let's clean this up a little bit let's just pass in some string here error and let's also add the then back which takes in a function and let's just log console.log success and let's see what happens now running this hello was executed but neither the then nor the catch was executed that's because our promise is still in a pending State neither resolve or reject was executed so our promise is in a pending State and in this case it'll be pending forever and the last thing worth knowing about promises in JavaScript is that there is the finally block which is executed regardless of whether the promise is resolved or rejected this can sometimes be good for like cleanup related tasks if there's some piece of code that you always want to execute which is basically in this case might just be console.log promise completed whether it's been resolved or rejected do you think it will execute in this case because our promise is not result evolved or rejected let's see what happened in this case no it was not completed but you'll see now when I get rid of this hello and I change this to a resolve and then rerun it we ended up getting success and promise completed but if I change this to a reject we'll get something similar which is error and Promise complete the finally executes regardless of whether the promise is resolved or rejected okay that's probably more than you ever wanted to know about promises but I promise you this is a very important concept no pun intended so now we can finally get back to the problem what were they asking for again oh yeah write an asynchronous function that sleeps for this many milliseconds and it can resolve to any value in this case let's return a promise well we have to construct one using the new keyword and we're going to take a callback which is a function I'm going to Define it down here because I think it makes it a tiny bit more clear well I probably have to Define it before I actually execute the return statement so let's move it up here here this is our callback we're going to be passing into the promise it's going to take two parameters remember resolve and reject and we want it to resolve to any value they say resolve not reject so we only need to execute the resolve and it should only happen after this many milliseconds well that's what our set timeout is for so we pass in resolve which resolve is a method remember we're not calling resolve we're passing resolve into the set timeout which will then be executed after this many milliseconds so this is our callback that we are now going to pass into the promise which is going to be returned and of course we could have just written this as like an inline function here which is typically how I write this kind of code but I think for beginners this might be a bit more readable so let's run this and as you can see yes it does work there's a couple last things I wanted to mention which is what does this asynchronous keyword mean well let's go back to our notepad here you can kind of see how this kind of code can get messy when we have so many callback acts like this and sometimes you can even have nested promises promises that return promises and things can get really messy there are other libraries for dealing with that sometimes but JavaScript has a built-in functionality which is a sync oh wait these are two key words that are really important when you make a function like this let's say hello and you make it an asynchronous function by default this will return a promise we know by default if this is not an asynchronous function it will return undefined right so if I call hello now and log it this is going to return undefined it's not returning anything so what's going to happen this is going to return undefined let's do that yep undefined and let's get rid of the code at the bottom so we don't confuse ourselves well I commented out but now if we change this to an asynchronous function now what's the return value going to be let's just run it and prove it to ourselves oh it's a promise because asynchronous the keyword will implicitly convert every function's return type into a promise so if I change this hello and I just return an actual string which is hello and run it it will do what we expect logs hello now if I change this to a sync though it returns a raw Miss which resolves to this string JavaScript does that under the hood which is really confusing for beginners or at least for me because I came from a language called C plus plus where you kind of have to manually do everything yourself now let's run this and see what happens oh we got a promise that resolves to hello and we can take it a bit further we can actually on this hello we can add that then keyword and once it resolves we can take that return value that it does resolve to which let's say is the response and then console log the response and you'll see that this should log the return value that we get from over here and it does indeed do exactly that so what's the point of the async keyword well it goes with another keyword called away and that allows us to not need to do these callbacks we can instead call hello then use the await keyword what this does is it kind of acts as the dot then keyword it's just another way of writing the same code we can call away on this and then get whatever the response happened to be like this and then console.log the response which should be the same let's run it to prove it okay this is a good error I think I know what's causing it but I'm going to get rid of this await keyword as well over here the await keyword can only be used in other asynchronous functions and the reason is that we don't want to block the main thread and in this case this is kind of like our entire program so we don't want to block the execution we have to use away in a function so let's actually just put all this code inside another function let's call it Helper and then move this code inside of there and now if we try it we're actually going to get another error because we have not made this function asynchronous so now let's make the function asynchronous and then let's actually call the function as well down here so executing Helper and then running this we did get hello basically a weight will say that this line of code must execute before the following lines of code within the same function if we change this without the await keyword that's not necessarily going to be the case and let's run it to actually prove that okay we got a promise which makes sense that's where hello is returning but I guess this line did end up executing before this because this isn't actually a real asynchronous function so let's actually change that and to do that I'm going to Define another method up here which is called Sleep which is basically the solution for our problem today I actually just I'm going to go ahead and copy and paste that and just clean this up a tad bit now this is in asynchronous function and here we're going to call sleep and we're gonna sleep let's say one second and we're also going to await because we don't just want sleep to execute and then immediately return hello we want to wait one second and then return hello so now we know when this code executes hello yes it's gonna execute but it's not immediately going to return the promise response so when we try to log that response let's see what happens oh we got a promise that is currently pending now if we want to actually wait for that promise to be completed before we log it we have to add the await keyword I hope you're starting to get the idea of why we have the async and await keyword it's just a different way of writing this I mean don't get me wrong this is definitely very very confusing the first time you see it I don't expect you to understand it entirely now let's run this now that we've added the await keyword and you see it waited a second right it didn't immediately console log because yes it did have to wait one second before executing the next line but it did get the actual response okay enough of all this let's get back to the second solution I wanted to show you thankfully it's not going to be super complicated remember what the problem is asking for just wait this many milliseconds and resolve to any value in here we actually don't even need to return anything we can create a promise which takes in a function which remember always has resolve and reject as parameters and then what it's going to do is it's going to execute set time out and it's going to resolve this promise so we're going to pass in resolve after this many milliseconds instead of returning this promise I'm just gonna await This Promise so normally this function would return undefined but since it's an asynchronous function this is returning a promise of undefined and that promise yes is going to resolve after this many milliseconds and we can do that because they mention it can resolve to any value we don't care what the value is we don't care even if it's undefined that's perfectly valid I guess so let's run this to make sure that it works and as you can see yes it does and it's pretty efficient if you found this helpful please like And subscribe this was a really fun video to make and hopefully I'll see you pretty soon

Original Description

Solving Day 11 of the Leetcode 30-day javascript challenge. Today's topic is async programming, probably the most important topic so far, and widely applicable to professional programming. 🚀 https://neetcode.io/ - A better way to prepare for Coding Interviews 🥷 Discord: https://discord.gg/ddjKRXPqtk 🐦 Twitter: https://twitter.com/neetcode1 🐮 Support the channel: https://www.patreon.com/NEETcode ⭐ BLIND-75 PLAYLIST: https://www.youtube.com/watch?v=KLlXCFG5TnA&list=PLot-Xpze53ldVwtstag2TL4HQhAnC8ATf 💡 DYNAMIC PROGRAMMING PLAYLIST: https://www.youtube.com/watch?v=73r3KWiEvyk&list=PLot-Xpze53lcvx_tjrr_m2lgD2NsRHlNO&index=1 Problem Link: https://leetcode.com/problems/sleep/ 0:00 - JavaScript vs Java (async nature) 0:50 - Understand problem 1:22 - setTimeout 2:43 - Promise Implementation 6:50 - Promise then 7:32 - Promise catch 10:26 - Promise finally 11:30 - Solution 1 12:45 - Async vs Await 18:00 - Solution 2 leetcode 2621 #neetcode #leetcode #python
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from NeetCodeIO · NeetCodeIO · 0 of 60

← Previous Next →
1 Leetcode 149 - Maximum Points on a Line - Python
Leetcode 149 - Maximum Points on a Line - Python
NeetCodeIO
2 Design Linked List - Leetcode 707 - Python
Design Linked List - Leetcode 707 - Python
NeetCodeIO
3 Minimum Time to Collect All Apples in a Tree - Leetcode 1443 - Python
Minimum Time to Collect All Apples in a Tree - Leetcode 1443 - Python
NeetCodeIO
4 Design Browser History - Leetcode 1472 - Python
Design Browser History - Leetcode 1472 - Python
NeetCodeIO
5 Number of Good Paths - Leetcode 2421 - Python
Number of Good Paths - Leetcode 2421 - Python
NeetCodeIO
6 Flip String to Monotone Increasing - Leetcode 926 - Python
Flip String to Monotone Increasing - Leetcode 926 - Python
NeetCodeIO
7 Maximum Sum Circular Subarray - Leetcode 918 - Python
Maximum Sum Circular Subarray - Leetcode 918 - Python
NeetCodeIO
8 Find Closest Node to Given Two Nodes - Leetcode 2359 - Python
Find Closest Node to Given Two Nodes - Leetcode 2359 - Python
NeetCodeIO
9 Concatenated Words - Leetcode 472 - Python
Concatenated Words - Leetcode 472 - Python
NeetCodeIO
10 Data Stream as Disjoint Intervals - Leetcode 352 - Python
Data Stream as Disjoint Intervals - Leetcode 352 - Python
NeetCodeIO
11 LFU Cache - Leetcode 460 - Python
LFU Cache - Leetcode 460 - Python
NeetCodeIO
12 N-th Tribonacci Number - Leetcode 1137
N-th Tribonacci Number - Leetcode 1137
NeetCodeIO
13 Best Team with no Conflicts - Leetcode 1626 - Python
Best Team with no Conflicts - Leetcode 1626 - Python
NeetCodeIO
14 Greatest Common Divisor of Strings - Leetcode 1071 - Python
Greatest Common Divisor of Strings - Leetcode 1071 - Python
NeetCodeIO
15 Shortest Path in a Binary Matrix - Leetcode 1091 - Python
Shortest Path in a Binary Matrix - Leetcode 1091 - Python
NeetCodeIO
16 Insert into a Binary Search Tree - Leetcode 701 - Python
Insert into a Binary Search Tree - Leetcode 701 - Python
NeetCodeIO
17 Delete Node in a BST - Leetcode 450 - Python
Delete Node in a BST - Leetcode 450 - Python
NeetCodeIO
18 Shuffle the Array (Constant Space) - Leetcode 1470 - Python
Shuffle the Array (Constant Space) - Leetcode 1470 - Python
NeetCodeIO
19 Fruits into Basket - Leetcode 904 - Python
Fruits into Basket - Leetcode 904 - Python
NeetCodeIO
20 Number of Subarrays of size K and Average Greater than or Equal to Threshold - Leetcode 1343 Python
Number of Subarrays of size K and Average Greater than or Equal to Threshold - Leetcode 1343 Python
NeetCodeIO
21 Naming a Company - Leetcode 2306 - Python
Naming a Company - Leetcode 2306 - Python
NeetCodeIO
22 As Far from Land as Possible - Leetcode 1162 - Python
As Far from Land as Possible - Leetcode 1162 - Python
NeetCodeIO
23 Shortest Path with Alternating Colors - Leetcode 1129 - Python
Shortest Path with Alternating Colors - Leetcode 1129 - Python
NeetCodeIO
24 Minimum Fuel Cost to Report to the Capital - Leetcode 2477 - Python
Minimum Fuel Cost to Report to the Capital - Leetcode 2477 - Python
NeetCodeIO
25 Count Odd Numbers in an Interval Range - Leetcode 1523 - Python
Count Odd Numbers in an Interval Range - Leetcode 1523 - Python
NeetCodeIO
26 Contains Duplicate II - Leetcode 219 - Python
Contains Duplicate II - Leetcode 219 - Python
NeetCodeIO
27 Path with Maximum Probability - Leetcode 1514 - Python
Path with Maximum Probability - Leetcode 1514 - Python
NeetCodeIO
28 Add to Array-Form of Integer - Leetcode 989 - Python
Add to Array-Form of Integer - Leetcode 989 - Python
NeetCodeIO
29 Unique Paths II - Leetcode 63 - Python
Unique Paths II - Leetcode 63 - Python
NeetCodeIO
30 Minimum Distance between BST Nodes - Leetcode 783 - Python
Minimum Distance between BST Nodes - Leetcode 783 - Python
NeetCodeIO
31 Design Hashmap - Leetcode 706 - Python
Design Hashmap - Leetcode 706 - Python
NeetCodeIO
32 Range Sum Query Immutable - Leetcode 303 - Python
Range Sum Query Immutable - Leetcode 303 - Python
NeetCodeIO
33 Binary Tree Zigzag Level Order Traversal - Leetcode 103 - Python
Binary Tree Zigzag Level Order Traversal - Leetcode 103 - Python
NeetCodeIO
34 Middle of the Linked List - Leetcode 876 - Python
Middle of the Linked List - Leetcode 876 - Python
NeetCodeIO
35 Course Schedule IV - Leetcode 1462 - Python
Course Schedule IV - Leetcode 1462 - Python
NeetCodeIO
36 Single Element in a Sorted Array - Leetcode 540 - Python
Single Element in a Sorted Array - Leetcode 540 - Python
NeetCodeIO
37 Capacity to Ship Packages - Leetcode 1011 - Python
Capacity to Ship Packages - Leetcode 1011 - Python
NeetCodeIO
38 IPO - Leetcode 502 - Python
IPO - Leetcode 502 - Python
NeetCodeIO
39 Minimize Deviation in Array - Leetcode 1675 - Python
Minimize Deviation in Array - Leetcode 1675 - Python
NeetCodeIO
40 Longest Turbulent Array - Leetcode 978 - Python
Longest Turbulent Array - Leetcode 978 - Python
NeetCodeIO
41 Last Stone Weight II - Leetcode 1049 - Python
Last Stone Weight II - Leetcode 1049 - Python
NeetCodeIO
42 Construct Quad Tree - Leetcode 427 - Python
Construct Quad Tree - Leetcode 427 - Python
NeetCodeIO
43 Find Duplicate Subtrees - Leetcode 652 - Python
Find Duplicate Subtrees - Leetcode 652 - Python
NeetCodeIO
44 Sort an Array - Leetcode 912 - Python
Sort an Array - Leetcode 912 - Python
NeetCodeIO
45 Ones and Zeroes - Leetcode 474 - Python
Ones and Zeroes - Leetcode 474 - Python
NeetCodeIO
46 Remove Duplicates from Sorted Array II - Leetcode 80 - Python
Remove Duplicates from Sorted Array II - Leetcode 80 - Python
NeetCodeIO
47 Maximum Twin Sum of a Linked List - Leetcode 2130 - Python
Maximum Twin Sum of a Linked List - Leetcode 2130 - Python
NeetCodeIO
48 Concatenation of Array - Leetcode 1929 - Python
Concatenation of Array - Leetcode 1929 - Python
NeetCodeIO
49 Symmetric Tree - Leetcode 101 - Python
Symmetric Tree - Leetcode 101 - Python
NeetCodeIO
50 Check Completeness of a Binary Tree - Leetcode 958 - Python
Check Completeness of a Binary Tree - Leetcode 958 - Python
NeetCodeIO
51 Construct Binary Tree from Inorder and Postorder Traversal - Leetcode 106 - Python
Construct Binary Tree from Inorder and Postorder Traversal - Leetcode 106 - Python
NeetCodeIO
52 Find Peak Element - Leetcode 162 - Python
Find Peak Element - Leetcode 162 - Python
NeetCodeIO
53 Accounts Merge - Leetcode 721 - Python
Accounts Merge - Leetcode 721 - Python
NeetCodeIO
54 Binary Tree Preorder Traversal (Iterative) - Leetcode 144 - Python
Binary Tree Preorder Traversal (Iterative) - Leetcode 144 - Python
NeetCodeIO
55 Binary Tree Postorder Traversal (Iterative) - Leetcode 145 - Python
Binary Tree Postorder Traversal (Iterative) - Leetcode 145 - Python
NeetCodeIO
56 Number of Zero-Filled Subarrays - Leetcode 2348 - Python
Number of Zero-Filled Subarrays - Leetcode 2348 - Python
NeetCodeIO
57 Minimum Score of a Path Between Two Cities - Leetcode 2492 - Python
Minimum Score of a Path Between Two Cities - Leetcode 2492 - Python
NeetCodeIO
58 Sqrt(x) - Leetcode 69 - Python
Sqrt(x) - Leetcode 69 - Python
NeetCodeIO
59 Successful Pairs of Spells and Potions - Leetcode 2300 - Python
Successful Pairs of Spells and Potions - Leetcode 2300 - Python
NeetCodeIO
60 Optimal Partition of String - Leetcode 2405 - Python
Optimal Partition of String - Leetcode 2405 - Python
NeetCodeIO

Related Reads

📰
O(N) Manacher's Algorithm with Mirror Boundary Optimization
Learn to optimize palindrome detection using Manacher's Algorithm with mirror boundary optimization, reducing time complexity to O(N)
Dev.to · Dipaditya Das
📰
Building a Power Grid Inside Minecraft with BFS Algorithms
Learn to build a power grid inside Minecraft using BFS algorithms and understand its relevance to cloud services
Dev.to · Carlos Cortez 🇵🇪 [AWS Hero]
📰
The Run-Length Encoding Trick: How Simple Strings Get Compressed
Learn how Run-Length Encoding (RLE) compresses simple strings, a fundamental technique in programming and data compression, and apply it to optimize storage and transmission of data
Medium · Programming
📰
75 Days of Leetcode — Day 4: #238 — Product of Array Except Self
Solve the Product of Array Except Self problem on LeetCode to improve coding skills and learn array manipulation techniques
Medium · AI

Chapters (10)

JavaScript vs Java (async nature)
0:50 Understand problem
1:22 setTimeout
2:43 Promise Implementation
6:50 Promise then
7:32 Promise catch
10:26 Promise finally
11:30 Solution 1
12:45 Async vs Await
18:00 Solution 2
Up next
Stump Grinder Carbide Wheel Grinds Hardwood To Chips
Innoforge Studio
Watch →