1 00:00:00,240 --> 00:00:06,090 In this video as promised we'll be taking a quick break from exploring new Mongo DB features to talk 2 00:00:06,090 --> 00:00:12,570 about something called Promises Promises make it easy for us to manage our asynchronous code and they 3 00:00:12,570 --> 00:00:18,680 were designed to solve many of the problems that we run into when using callbacks in our application. 4 00:00:18,690 --> 00:00:25,140 Now you might be wondering why now why learn about callbacks and use them for so long only to replace 5 00:00:25,140 --> 00:00:31,620 them with promises promises actually build on the callback pattern so it's necessary to understand how 6 00:00:31,620 --> 00:00:35,760 callbacks work and how we can use them before we'll be able to understand. 7 00:00:35,760 --> 00:00:42,420 Promises promises are nothing more than an enhancement for callbacks making it a bit easier to manage 8 00:00:42,450 --> 00:00:44,040 our asynchronous code. 9 00:00:44,040 --> 00:00:49,860 The goal of this video is to give us our first exposure to promises to explore what they are and how 10 00:00:49,860 --> 00:00:50,540 they work. 11 00:00:50,610 --> 00:00:56,570 In the following videos we'll actually integrate promises into our Mongo DB code. 12 00:00:56,610 --> 00:01:01,890 For now though I'm actually going to close this file down and we're going to move over to the playground 13 00:01:01,920 --> 00:01:03,720 directory in here. 14 00:01:03,720 --> 00:01:10,980 We're going to create a brand new file eight hyphen promises Don J S and in here we're going to work 15 00:01:10,980 --> 00:01:12,600 with a promise example. 16 00:01:12,770 --> 00:01:18,600 Now to really understand how promises work it's best to compare and contrast them with each additional 17 00:01:18,600 --> 00:01:20,040 callback pattern. 18 00:01:20,040 --> 00:01:24,390 Now I have this file for height and callbacks from earlier in the class. 19 00:01:24,390 --> 00:01:28,540 If you don't have that or you don't have any content inside of there that's OK. 20 00:01:28,620 --> 00:01:34,260 I'm actually gonna be emptying this file out too and starting with a basic callback example. 21 00:01:34,290 --> 00:01:40,800 Then we'll see how we can do the exact same thing using promises so allow us to view these files side 22 00:01:40,800 --> 00:01:41,510 by side. 23 00:01:41,520 --> 00:01:47,170 What I'm gonna do is double click this little file icon to close down the tree view. 24 00:01:47,280 --> 00:01:48,990 Then I'm going to split the editors. 25 00:01:48,990 --> 00:01:55,200 Side by side I'll have callbacks over here on the left and I'll have the premises file over here on 26 00:01:55,200 --> 00:01:55,850 the right. 27 00:01:55,980 --> 00:01:59,790 And we're going to spend the whole video just working with these two files. 28 00:01:59,790 --> 00:02:01,830 Let's get started with the callback example. 29 00:02:01,830 --> 00:02:04,000 Then we'll convert it over to promises. 30 00:02:04,020 --> 00:02:10,010 What I'm gonna do is create a new function something like do work callback and we'll create do work 31 00:02:10,020 --> 00:02:13,080 promise over in the promises file shortly. 32 00:02:13,080 --> 00:02:17,790 Now this is going to be a function that performs some sort of made up asynchronous task. 33 00:02:17,880 --> 00:02:24,000 We're going to simulate a delay using set time out and we'll do the same thing with promises just to 34 00:02:24,000 --> 00:02:25,550 explore the basic syntax. 35 00:02:25,560 --> 00:02:29,000 But don't worry we will learn how to use promises in the real world. 36 00:02:29,010 --> 00:02:35,340 Shortly we'll be using them for everything including connecting to mongo D.B. to read write update and 37 00:02:35,340 --> 00:02:36,830 delete our data. 38 00:02:36,870 --> 00:02:43,270 For now though we have do work call back and we can go ahead and call that do work callback and the 39 00:02:43,270 --> 00:02:48,880 whole point of using the callback pattern as a way to allow the caller of due work callback to get the 40 00:02:48,880 --> 00:02:49,810 results. 41 00:02:49,830 --> 00:02:56,190 So I provide a callback function and this function runs when I have either the error or the result. 42 00:02:56,200 --> 00:03:01,390 So right here the first argument is for the error and the second argument is for the result. 43 00:03:01,450 --> 00:03:07,480 We've seen this pattern with all of our callback functions including those from mongo D.B.. 44 00:03:07,630 --> 00:03:13,090 So from here we can go ahead and do things with the error or the result before we do though. 45 00:03:13,110 --> 00:03:15,440 Let's start filling out do work callback. 46 00:03:15,520 --> 00:03:18,850 We know we're getting an argument passed in when the function is called. 47 00:03:18,850 --> 00:03:23,040 So up here I will name that parameter and it's typically called callback. 48 00:03:23,050 --> 00:03:29,230 Though I could call it whatever I'd like and down below we'll start the process of simulating that asynchronous 49 00:03:29,230 --> 00:03:30,190 process. 50 00:03:30,190 --> 00:03:34,000 So right here we'll be using set time out to get that done. 51 00:03:34,090 --> 00:03:39,390 We provide the function to run after the set amount of time and the amount of time we'd like to wait. 52 00:03:39,550 --> 00:03:39,900 I'll wait. 53 00:03:39,910 --> 00:03:46,600 Two thousand milliseconds which is just two seconds now from here the asynchronous task is complete 54 00:03:46,840 --> 00:03:53,440 and we can signal to the caller that we either got an error or we got a result we got the correct success 55 00:03:53,500 --> 00:03:54,980 data right here. 56 00:03:55,090 --> 00:03:59,760 We do that by calling callback with one of two arguments if things went poorly. 57 00:03:59,800 --> 00:04:06,610 We provide just the first argument and in this case I could have a string like this is my error. 58 00:04:06,670 --> 00:04:08,830 The second argument would be undefined. 59 00:04:08,920 --> 00:04:15,040 We could set it to undefined by not providing it at all or by explicitly setting it to undefined like 60 00:04:15,040 --> 00:04:16,140 we're seeing here. 61 00:04:16,150 --> 00:04:19,520 Either way would work now with the callback pattern. 62 00:04:19,600 --> 00:04:24,580 We have to put a little bit of conditional logic in here because this is the only function that runs 63 00:04:24,820 --> 00:04:28,470 it runs for both failures and for successes. 64 00:04:28,510 --> 00:04:32,640 That means we use patterns like what we've seen plenty of times in the course. 65 00:04:33,160 --> 00:04:39,490 If there is an error we want to run some special code I'll be using return to stop the function execution 66 00:04:39,790 --> 00:04:44,400 and I'll go ahead and use console dot log to dump the error to the terminal. 67 00:04:44,800 --> 00:04:49,600 If there is no error then we must have gotten a result and down below we could go ahead and dump that 68 00:04:49,810 --> 00:04:51,760 to the terminal as well. 69 00:04:51,760 --> 00:04:57,100 So right here we have a very basic example of the callback pattern and we can go ahead and run this 70 00:04:57,100 --> 00:05:01,060 program before continuing on in the terminal down below. 71 00:05:01,060 --> 00:05:02,260 I'll use C D. 72 00:05:02,260 --> 00:05:08,590 Dot dot forward slash playground to navigate over to that playground directory and from here we'll run 73 00:05:08,590 --> 00:05:16,250 our file node for callbacks dot J S when we run it. 74 00:05:16,290 --> 00:05:17,400 What are we going to see. 75 00:05:17,400 --> 00:05:23,160 Well after that two second delay I would expect to see my error message and that is exactly what I get 76 00:05:23,250 --> 00:05:24,330 right here. 77 00:05:24,330 --> 00:05:30,690 Now if things went well we could signify that by calling callback with a different set of arguments 78 00:05:30,840 --> 00:05:32,390 instead of providing the first. 79 00:05:32,400 --> 00:05:34,400 We would just provide the second. 80 00:05:34,410 --> 00:05:43,090 So right here I can do something like Call callback providing undefined which would be the error value. 81 00:05:43,090 --> 00:05:48,730 And then for the second argument providing those success results let's say in this case we're getting 82 00:05:48,730 --> 00:05:50,050 an array of numbers back. 83 00:05:50,050 --> 00:05:52,810 I'll use 1 4 and 7. 84 00:05:52,960 --> 00:05:58,960 Now if I was to save the program and rerun things we should see our numbers printing after two seconds 85 00:05:58,990 --> 00:05:59,800 and down below. 86 00:05:59,800 --> 00:06:06,190 That's exactly what we're getting because result had a value down here the error code didn't run and 87 00:06:06,190 --> 00:06:08,320 we got our result printing. 88 00:06:08,320 --> 00:06:11,750 So this is the callback pattern we've seen plenty of times before. 89 00:06:11,830 --> 00:06:17,680 I wanted to work through it one more time just so we had a side by side comparison between how these 90 00:06:17,680 --> 00:06:19,940 two different setups work. 91 00:06:19,960 --> 00:06:25,000 So with callbacks we can see that the order we call the callback is important. 92 00:06:25,000 --> 00:06:28,510 The first one being the error and the second being the result. 93 00:06:28,580 --> 00:06:33,340 And we can also see that down below we add a little bit of conditional logic to figure out if things 94 00:06:33,340 --> 00:06:36,150 went well or if they went poorly. 95 00:06:36,160 --> 00:06:38,200 Now let's go ahead and do the same thing. 96 00:06:38,230 --> 00:06:44,460 But using the new promises API for the promises example we'll be starting off much the same way. 97 00:06:44,500 --> 00:06:51,520 I'm going to create a new constant called do work promise and I'll set this equal to a new promise. 98 00:06:51,520 --> 00:06:52,900 Now to create a promise. 99 00:06:52,900 --> 00:06:57,390 We use the new operator with the promise constructor function. 100 00:06:57,460 --> 00:06:59,190 So we call it like this. 101 00:06:59,290 --> 00:07:04,750 Now most of the time we as know developers we're not going to be the ones creating promises. 102 00:07:04,750 --> 00:07:11,420 Typically they'll be created by the libraries we use as an example when we use promises with Mongo D.B.. 103 00:07:11,500 --> 00:07:14,620 We're not actually going to create new promises at all. 104 00:07:14,620 --> 00:07:18,700 All of that happens behind the scenes inside of the library itself. 105 00:07:18,700 --> 00:07:24,690 But to understand how promises work it's essential to at least become familiar with this syntax. 106 00:07:24,820 --> 00:07:29,370 Now when we call new promise we provide it to it just a single argument. 107 00:07:29,380 --> 00:07:34,240 That is a function and we could make this an arrow function and that would work just fine though you 108 00:07:34,240 --> 00:07:37,620 could also use a standard function if you wanted to. 109 00:07:37,630 --> 00:07:46,180 This function gets called by the promise API and we get access to two arguments we have first up resolve. 110 00:07:46,240 --> 00:07:52,810 And second we have reject and we'll end up using both of these as we move through the process of completing 111 00:07:52,840 --> 00:07:54,680 our asynchronous task. 112 00:07:54,700 --> 00:08:00,250 Now for us that task is still going to be just simulating a delay using set time out. 113 00:08:00,250 --> 00:08:03,300 So let's go ahead and get to it right here. 114 00:08:03,520 --> 00:08:08,380 Set time out passing in our function and the amount of time we'd like to wait. 115 00:08:08,470 --> 00:08:10,810 Once again I'll just wait two seconds. 116 00:08:10,810 --> 00:08:18,190 Now when it's done we are ready to signify that we've completed the asynchronous process in the past 117 00:08:18,190 --> 00:08:23,470 with the callback pattern we would signify this by calling the callback in one of two ways. 118 00:08:23,560 --> 00:08:29,170 I would provide that first argument if things failed and I would provide the second argument if things 119 00:08:29,200 --> 00:08:31,240 succeeded in our case. 120 00:08:31,240 --> 00:08:33,730 What we have are two separate functions. 121 00:08:33,730 --> 00:08:41,020 I have resolve and reject if things went well and we got the result we were expecting we call resolve. 122 00:08:41,020 --> 00:08:46,610 If things went poorly and we did not get the result we were expecting we would call reject. 123 00:08:47,020 --> 00:08:52,990 So right here we're gonna see some clearer semantics when working with promises it can be a bit difficult 124 00:08:52,990 --> 00:08:59,290 to easily figure out that this means success and this means failure because the order of arguments plays 125 00:08:59,290 --> 00:09:01,290 an important role over here. 126 00:09:01,300 --> 00:09:04,710 The name of the functions clearly signifies that. 127 00:09:04,810 --> 00:09:09,050 So what I'm going to do is use resolve to say that things went well. 128 00:09:09,070 --> 00:09:16,450 Now we can pass to resolve and to reject a single value so as an example if I was calling reject I would 129 00:09:16,450 --> 00:09:22,180 pass in my error if I was calling resolve I would pass in my success information. 130 00:09:22,180 --> 00:09:27,450 In this case since I am calling resolve I'll pass in another array of numbers to signify that we've 131 00:09:27,450 --> 00:09:32,690 got the results we were expecting right here 7 4 and 1. 132 00:09:32,830 --> 00:09:33,790 Perfect. 133 00:09:33,880 --> 00:09:39,370 So at this point we actually have the promise created it's going to wait those 2 seconds then it's going 134 00:09:39,370 --> 00:09:41,860 to signify that things went well. 135 00:09:41,860 --> 00:09:48,170 The question is what's the other half what we have here is essentially equivalent to what we have here. 136 00:09:48,190 --> 00:09:53,840 How exactly though do we do something when the asynchronous process is complete down below. 137 00:09:53,860 --> 00:09:58,230 We do that by using various methods on do work promise. 138 00:09:58,240 --> 00:10:04,570 Now in this example do work promise is the actual promise and a promise is nothing more than an object 139 00:10:04,600 --> 00:10:07,480 with a few methods that we can access down below. 140 00:10:07,480 --> 00:10:11,200 Let's go ahead and explore them do work. 141 00:10:11,200 --> 00:10:19,180 Promise DOT and the first method we're gonna use is dot then dot then allows us to register a function 142 00:10:19,180 --> 00:10:26,560 to run when things go well so when resolved is called right here we can set up that function and we 143 00:10:26,560 --> 00:10:27,960 get access to the data. 144 00:10:27,970 --> 00:10:30,170 The promise was resolved with. 145 00:10:30,280 --> 00:10:32,090 This first and only parameter. 146 00:10:32,140 --> 00:10:38,370 So right here I can call that result and result lines up with what we had over here called the result. 147 00:10:38,410 --> 00:10:42,590 So this function only gets executed when things go well. 148 00:10:42,690 --> 00:10:47,340 Right here I'm going to use console dot log to print two things. 149 00:10:47,340 --> 00:10:54,720 First up I will print success then as the second argument to console dot log I'll dump the result variable 150 00:10:54,780 --> 00:10:55,950 to the screen. 151 00:10:55,950 --> 00:11:00,030 Let's go ahead and run the program and see what we get down below. 152 00:11:00,030 --> 00:11:07,860 That's gonna be node 8 hyphen promises dot J S and when I execute it we still wait those two seconds 153 00:11:07,870 --> 00:11:12,350 since promises help us maintain and manage our asynchronous code. 154 00:11:12,410 --> 00:11:17,430 Then after those two seconds are up we got success and we got our data. 155 00:11:17,430 --> 00:11:19,160 Now things don't always go well. 156 00:11:19,170 --> 00:11:24,540 If we're using promises to query the database maybe the network connection drops and we can't access 157 00:11:24,540 --> 00:11:26,190 the database server. 158 00:11:26,190 --> 00:11:28,320 In that case we wouldn't call resolve. 159 00:11:28,320 --> 00:11:35,310 Instead we would go ahead and call reject now reject is similar to resolve in the fact that it accepts 160 00:11:35,310 --> 00:11:37,430 just a single optional argument. 161 00:11:37,500 --> 00:11:39,930 And in this case that would be the error. 162 00:11:39,930 --> 00:11:45,330 So that would be similar to what we would pass as the first argument to our callback function in the 163 00:11:45,330 --> 00:11:47,560 callback example right here. 164 00:11:47,700 --> 00:11:49,650 I'll go ahead and do just that. 165 00:11:49,800 --> 00:11:50,970 I'll print the message. 166 00:11:50,970 --> 00:11:53,550 Things went wrong. 167 00:11:53,580 --> 00:11:54,640 Perfect. 168 00:11:54,690 --> 00:11:58,380 Now when we call reject this function is not going to run. 169 00:11:58,380 --> 00:12:01,700 Remember this only runs if things go well. 170 00:12:01,800 --> 00:12:07,220 Right here we can chain on a another method call to the catch method. 171 00:12:07,350 --> 00:12:12,170 And this allows us to register a function to run when reject is called. 172 00:12:12,180 --> 00:12:19,290 So right here what I'm gonna do is pass in that function we're going to get access to the error and 173 00:12:19,290 --> 00:12:20,970 then we can go ahead and use it. 174 00:12:20,970 --> 00:12:24,660 So right here I'm just going to dump it console dot log. 175 00:12:24,750 --> 00:12:26,970 First up I will print error. 176 00:12:26,970 --> 00:12:31,010 Then I'll actually dump the variable value to the terminal. 177 00:12:31,020 --> 00:12:35,520 Now with this in place let's go ahead and run the example once again from the terminal. 178 00:12:35,520 --> 00:12:40,200 We're gonna wait our 2 seconds and when the two seconds are up we get things went wrong. 179 00:12:40,200 --> 00:12:41,540 Printing to the terminal. 180 00:12:41,580 --> 00:12:47,190 Now right away there are some clear advantages to working with promises one is clearer semantics it's 181 00:12:47,190 --> 00:12:50,480 easier to understand the intention of the code. 182 00:12:50,520 --> 00:12:53,490 So over here we have resolve and reject. 183 00:12:53,490 --> 00:12:59,070 We have two separate functions we call and that makes it easier to just pass this code and figure out 184 00:12:59,100 --> 00:12:59,940 what's going on. 185 00:13:00,240 --> 00:13:04,050 If resolve is called We know things went well and this is our data. 186 00:13:04,320 --> 00:13:10,340 If reject was called we know that things went poorly and this is the error with the callback pattern. 187 00:13:10,380 --> 00:13:15,810 We just have these single function which means we need to look at all calls to callback and then figure 188 00:13:15,810 --> 00:13:18,450 out which of the two arguments was provided. 189 00:13:18,450 --> 00:13:25,080 Which is more error prone and easier to run into issues with the next benefit has to do with the setup 190 00:13:25,080 --> 00:13:30,290 we have for doing something when an asynchronous task is complete with a callback pattern. 191 00:13:30,290 --> 00:13:32,100 We have just a single function. 192 00:13:32,100 --> 00:13:38,040 It's up to us the developers to determine whether or not an error occurred and run the correct code. 193 00:13:38,040 --> 00:13:41,070 We did that using the if statement up above. 194 00:13:41,070 --> 00:13:44,640 When we're working with promises we have two separate functions. 195 00:13:44,640 --> 00:13:47,490 Only one of which will ever run down below. 196 00:13:47,490 --> 00:13:53,820 For example when reject was called we got our error printing which means that this function did indeed 197 00:13:53,850 --> 00:13:56,350 run it but we never got success printing. 198 00:13:56,370 --> 00:13:58,870 Which means that this function never ran. 199 00:13:58,970 --> 00:14:03,700 So with promises it's not up to us to add that conditional logic into place. 200 00:14:03,720 --> 00:14:09,870 We provide two separate functions making it easier for us to manage our asynchronous tasks. 201 00:14:09,870 --> 00:14:15,510 One more advantage of working with promises is that it makes it easy to not mess up and what I mean 202 00:14:15,510 --> 00:14:19,420 by that has to do with this function right here in this function. 203 00:14:19,440 --> 00:14:22,510 We can call either resolve or reject. 204 00:14:22,590 --> 00:14:25,590 We can't call both and we can't call one of them twice. 205 00:14:25,590 --> 00:14:30,570 I can't reject two times once either resolve or reject is called. 206 00:14:30,570 --> 00:14:37,500 The promise is done and its value or state can't change so we can't change the error message by calling 207 00:14:37,500 --> 00:14:42,600 reject again and I couldn't bring it from a failure to a success by calling resolve. 208 00:14:42,600 --> 00:14:47,320 Down below there's nothing built into the callback pattern to prevent that. 209 00:14:47,340 --> 00:14:52,370 So over here there's nothing to stop me from running this code and calling callback twice. 210 00:14:52,380 --> 00:14:57,810 Now this doesn't make any sense at all because our asynchronous operation should have either worked 211 00:14:57,870 --> 00:14:59,030 or not worked. 212 00:14:59,100 --> 00:15:02,520 It shouldn't have had both occur with promises. 213 00:15:02,520 --> 00:15:07,220 We don't have to worry about that and let's go ahead and quickly prove it down below what I'm gonna 214 00:15:07,230 --> 00:15:09,280 do is try to call resolve. 215 00:15:09,390 --> 00:15:15,060 I'm going to call resolve and I'm going to pass in some data to 3 and 2. 216 00:15:15,060 --> 00:15:20,940 This call is not going to cause the program to crash but it's going to have no effect on how the program 217 00:15:20,940 --> 00:15:22,460 runs at this point. 218 00:15:22,470 --> 00:15:28,710 When reject is called the premise stops looking for new calls to resolve or reject. 219 00:15:28,800 --> 00:15:31,320 Down below I'll go ahead and run the program. 220 00:15:31,320 --> 00:15:34,590 We wait our two seconds and we get our error message. 221 00:15:34,590 --> 00:15:37,970 At no point do we see the success message with this data. 222 00:15:38,870 --> 00:15:42,410 Now the same is true with trying to call the same method again. 223 00:15:42,410 --> 00:15:47,240 So for example I can't call reject providing a new error. 224 00:15:47,240 --> 00:15:49,130 That's not gonna work either. 225 00:15:49,130 --> 00:15:54,980 If I do go ahead and run the program for a final time we're going to see that we only get the first 226 00:15:55,040 --> 00:15:56,580 error showing up. 227 00:15:56,580 --> 00:16:03,110 So with promises there are rules enforced behind the scenes that makes it a bit easier to not mess up 228 00:16:03,140 --> 00:16:09,170 so it makes it easier to get the desired behavior that we're looking for and it makes it easier to squash 229 00:16:09,230 --> 00:16:11,480 those pesky asynchronous bugs. 230 00:16:11,480 --> 00:16:16,790 Now let's wrap up the video by talking about one of my favorite things with any new programming feature 231 00:16:16,820 --> 00:16:18,180 vocabulary. 232 00:16:18,230 --> 00:16:23,690 So as we're using promises we want to be able to discuss what's happening using terms that make sense 233 00:16:23,690 --> 00:16:24,700 for all of us. 234 00:16:24,710 --> 00:16:27,470 Now we're only going to introduce three new terms. 235 00:16:27,470 --> 00:16:33,440 Down below I have a series of JavaScript comments that create a little visualization. 236 00:16:33,530 --> 00:16:35,670 So right here we have a promise. 237 00:16:35,780 --> 00:16:39,860 When we first create the promise the promise is known as pending. 238 00:16:40,160 --> 00:16:47,750 So our promise is pending for the two seconds before resolve or reject is called a promise is pending 239 00:16:47,750 --> 00:16:51,560 until either resolve or reject is executed. 240 00:16:51,560 --> 00:16:59,330 Now if resolve is called your promise is considered the filled if reject is called your promise is considered 241 00:16:59,420 --> 00:17:00,520 rejected. 242 00:17:00,530 --> 00:17:05,120 So in our case I could say that I have a promise called do work promise. 243 00:17:05,120 --> 00:17:08,180 It's pending for two seconds and then it's rejected. 244 00:17:08,180 --> 00:17:15,080 If I were to flip the switch on these comments and call resolve and comment out reject I would say I 245 00:17:15,080 --> 00:17:17,060 have a do work promise. 246 00:17:17,060 --> 00:17:20,860 It's pending for two seconds then the promise is fulfilled. 247 00:17:21,080 --> 00:17:26,120 So it's important to just be familiar with these three terms as they're going to come up as we discuss 248 00:17:26,120 --> 00:17:27,410 promises. 249 00:17:27,410 --> 00:17:31,120 Now this is just the beginning with our work on promises. 250 00:17:31,130 --> 00:17:35,240 You're probably wondering what does this all look like in a real situation. 251 00:17:35,240 --> 00:17:40,030 Well it's actually pretty similar to what we see right here in the next video. 252 00:17:40,040 --> 00:17:46,460 You're going to learn how to use promises with Mongo D.B. since Mongo D.B. has built in support for 253 00:17:46,460 --> 00:17:47,090 them. 254 00:17:47,090 --> 00:17:51,730 We're gonna talk about updating our documents and we'll do so using promises. 255 00:17:51,740 --> 00:17:56,630 Now I have more to say about other promise features but we'll discuss those throughout the course as 256 00:17:56,630 --> 00:17:58,310 they become necessary. 257 00:17:58,310 --> 00:18:00,000 I'm excited to continue on. 258 00:18:00,020 --> 00:18:03,050 Let's go ahead and jump right in to the next video.