1 00:00:02,260 --> 00:00:09,600 Now I cleared the play.js file again because to conclude this quick refresher module, I'll dive into 2 00:00:09,670 --> 00:00:17,140 another core concept and that is how to work with asynchronous code and for that, we first of all have 3 00:00:17,140 --> 00:00:20,470 to understand what asynchronous code is. 4 00:00:20,530 --> 00:00:25,170 Let's say I set a timer with set timeout which is a function built into nodejs, 5 00:00:25,260 --> 00:00:31,900 there we define a function that should execute after a certain timer expired, 6 00:00:31,900 --> 00:00:33,880 here I'll use an arrow function, 7 00:00:33,880 --> 00:00:37,000 you could use a named function, whatever you like. 8 00:00:37,060 --> 00:00:39,970 The second argument is the timer, let's say two seconds, 9 00:00:40,090 --> 00:00:48,260 you express it in milliseconds so two seconds are 2000milliseconds. In there I'll simply log 10 00:00:48,260 --> 00:00:52,540 timer is done, 11 00:00:52,670 --> 00:00:59,090 if I now run this file for two seconds, nothing happens and then we see timer is done. 12 00:00:59,360 --> 00:01:02,750 Now this is asynchronous code because it doesn't finish immediately 13 00:01:03,030 --> 00:01:06,790 and it would even be async code if we had one millisecond there, 14 00:01:06,800 --> 00:01:11,010 so if it's super fast, it does not happen immediately. 15 00:01:11,300 --> 00:01:24,940 In other code snippets like if we have console log hello and console log hi, these two snippets are 16 00:01:24,940 --> 00:01:28,580 synchronous code because they are executed right after each other 17 00:01:28,660 --> 00:01:34,810 and yeah technically of course node will take some time to execute them but there is no delay other than 18 00:01:34,810 --> 00:01:35,820 your hardware 19 00:01:35,860 --> 00:01:43,390 so to say and therefore this is synchronous code, this is async code, asynchronous because it does not 20 00:01:43,480 --> 00:01:45,230 execute or finish immediately, 21 00:01:45,250 --> 00:01:49,000 it takes a little time even if that's super short. 22 00:01:49,000 --> 00:01:52,940 And indeed if I execute this file like this, you see hello 23 00:01:52,960 --> 00:01:53,560 and hi 24 00:01:53,620 --> 00:02:01,570 before you see timer's done even though it's super fast because nodejs and Javascript in general does 25 00:02:01,570 --> 00:02:10,900 not block your code execution until that is done, indeed here it will recognize this so-called callback 26 00:02:10,900 --> 00:02:11,860 function, 27 00:02:11,980 --> 00:02:18,730 so a function that should execute in the future, it should call back later once it is done so once this 28 00:02:18,730 --> 00:02:25,270 timer expired here, it will just recognize that and will then immediately move onto the next line 29 00:02:25,510 --> 00:02:32,320 and it will execute all the synchronous code and then execute your async code once this is done. 30 00:02:32,350 --> 00:02:34,080 Which is why we see hello and hi 31 00:02:34,080 --> 00:02:40,870 first even though in our code, timer is done is printed first. And that is a crucial concept you have to understand 32 00:02:40,870 --> 00:02:46,360 in javascript and especially node and I will come back to that throughout the course because it's 33 00:02:46,360 --> 00:02:54,280 so important. Now when working with that and I'll increase this to 2 seconds again to make it even clearer, 34 00:02:54,280 --> 00:02:59,210 then you will see again our sync code runs and then after two seconds, this code runs. 35 00:02:59,650 --> 00:03:06,310 When working with async code, we get multiple techniques of well handling it. 36 00:03:06,310 --> 00:03:08,250 The callback function is one, 37 00:03:08,320 --> 00:03:12,630 the oldest one and you'll see it quite a bit especially in nodejs. 38 00:03:12,690 --> 00:03:20,990 There is nothing wrong with it but you'll face a problem if you have a couple of depending async operations, 39 00:03:21,010 --> 00:03:27,280 so here we set the timer and now let's say I create another function 40 00:03:29,950 --> 00:03:32,700 which I'll name fetch data 41 00:03:34,380 --> 00:03:40,390 and in there, I will also just set a timer because I don't want to set up some database or something 42 00:03:40,540 --> 00:03:44,140 like that where we fetch data from, we'll do all that throughout the course, of course 43 00:03:44,140 --> 00:03:44,910 no worries. 44 00:03:45,250 --> 00:03:52,750 So here again I have another timer in there which takes like one and a half seconds 45 00:03:52,960 --> 00:04:01,730 and now here in fetch data, I need some way of well doing something when this inner timer is done. 46 00:04:01,750 --> 00:04:07,270 So here I will actually expect an argument which I'll name callback because this argument will be a 47 00:04:07,270 --> 00:04:13,990 function I will eventually call in my inner function here once I'm done with the timer and there I can 48 00:04:13,990 --> 00:04:16,030 pass done as a value. 49 00:04:16,140 --> 00:04:23,230 Now in the place where I use fetch data, let's say that's inside of this set timeout call, I call fetch 50 00:04:23,230 --> 00:04:24,370 data like this, 51 00:04:24,370 --> 00:04:27,600 there I now need to pass another callback 52 00:04:27,940 --> 00:04:34,400 and here I will get the text passed by the callback in my function when I execute it, 53 00:04:34,570 --> 00:04:39,970 so we'll get some text here and here I can console log that text. 54 00:04:39,970 --> 00:04:45,340 Now this might look confusing, in the end here I'm creating my own function which gets a callback so 55 00:04:45,340 --> 00:04:51,010 that I can define a function which should execute once this inner timer is done from some other place, 56 00:04:51,010 --> 00:04:56,590 so from this place here, this is the function which effectively is passed in as the callback and I'm executing 57 00:04:56,590 --> 00:04:57,910 that function here. 58 00:04:58,330 --> 00:05:04,700 Now if I save that and I run that, takes 2 seconds then the timer is done 59 00:05:04,730 --> 00:05:07,430 and then after one and a half seconds, I see done. 60 00:05:07,460 --> 00:05:15,160 Now if we have a couple of nested async calls as we have here, we go deeper and deeper from a callback 61 00:05:15,170 --> 00:05:16,320 perspective 62 00:05:16,790 --> 00:05:24,680 and that is why we also have a feature called promises which we can use in nodejs. Now often we'll use 63 00:05:24,680 --> 00:05:28,400 third party packages that already use promises for us, 64 00:05:28,400 --> 00:05:33,060 so the syntax I'll show you now is one you rarely have to write on your own, 65 00:05:33,260 --> 00:05:36,350 that will be done by the packages behind the scenes, 66 00:05:36,350 --> 00:05:45,380 still nice to know. You create a promise inside of our fetch data function here let's say by storing 67 00:05:45,380 --> 00:05:50,410 it in a constant or variable and then by using the new keyword which you use in javascript to create 68 00:05:50,410 --> 00:05:52,920 a new object based on a constructor. 69 00:05:53,090 --> 00:05:57,190 If constructor functions are something that tells you nothing, 70 00:05:57,200 --> 00:06:04,010 check out some basic introduction resource to javascript because constructor functions are a core feature 71 00:06:04,160 --> 00:06:05,450 in Javascript 72 00:06:05,690 --> 00:06:13,080 and here you use the promise constructor function which is built into javascript and nodejs and 73 00:06:13,080 --> 00:06:18,790 this actually also takes a callback which gets two arguments, resolve and reject, 74 00:06:18,840 --> 00:06:24,450 you could name them however you want but these are two functions and the first one completes the promise 75 00:06:24,450 --> 00:06:25,470 successfully, 76 00:06:25,470 --> 00:06:27,620 it resolves it successfully, 77 00:06:27,660 --> 00:06:32,120 the second one rejects it which is like throwing an error. 78 00:06:32,130 --> 00:06:35,120 You then take your async code and move that into there 79 00:06:35,150 --> 00:06:38,090 and again you rarely have to write this on your own, 80 00:06:38,100 --> 00:06:43,410 most packages already do that for you and give you the finished promise which does all the magic behind 81 00:06:43,410 --> 00:06:44,100 the scenes 82 00:06:44,100 --> 00:06:45,470 hidden away from you, 83 00:06:45,600 --> 00:06:47,190 here we do it manually. 84 00:06:47,220 --> 00:06:51,720 So now in that callback we have our own function, set 85 00:06:51,720 --> 00:06:57,060 timeout does not give us a promise API unfortunately, so here we also have to use a callback 86 00:06:57,450 --> 00:07:06,480 but in there, we now no longer use any callback function we get, I get no argument here in fetch 87 00:07:06,480 --> 00:07:07,540 data anymore 88 00:07:07,780 --> 00:07:11,520 instead here, I resolve done let's say, 89 00:07:11,520 --> 00:07:15,300 so I successfully return the resolve value. 90 00:07:15,540 --> 00:07:21,040 Now in fetch data after defining the promise, we just have to return it 91 00:07:21,120 --> 00:07:24,070 and please note this is synchronous code 92 00:07:24,240 --> 00:07:29,940 so actually this will be returned immediately after the promise gets created before the code in the 93 00:07:29,940 --> 00:07:36,660 promises run which will happen sometime later when we actually call that function and when this timer 94 00:07:36,660 --> 00:07:38,240 then completes. 95 00:07:38,280 --> 00:07:44,760 So we now return that promise here and in the place where we call fetch data, we now no longer pass a 96 00:07:44,760 --> 00:07:54,450 callback but we can now use then which is callable on a promise and we return a promise and this simply 97 00:07:54,750 --> 00:08:00,980 allows you to now define the callback function here which will execute once the promise is resolved. 98 00:08:04,080 --> 00:08:06,170 Now what is the advantage of that? 99 00:08:06,420 --> 00:08:13,080 If we had multiple such promises, so let's say I called fetch data again in there, 100 00:08:13,390 --> 00:08:23,510 then I don't have to use then like this and therefore I would end up with nested callbacks again 101 00:08:24,280 --> 00:08:31,050 but instead inside of a promise and then block is part of a promise, 102 00:08:31,180 --> 00:08:42,300 I can just return a new promise and then add the next then block after the previous one, like this. 103 00:08:42,310 --> 00:08:43,710 So now we have a chain of 104 00:08:43,780 --> 00:08:50,620 then blocks, this one gets called on the first promise, then in the then block, I return another promise 105 00:08:50,680 --> 00:08:56,920 and even if that would not give us a promise, instead of a then block returning it would convert it to 106 00:08:56,920 --> 00:09:00,610 a promise that instantly resolves and then we add another 107 00:09:00,610 --> 00:09:07,080 then block which is now referring to this promise here and this is more readable than having infinitely 108 00:09:07,090 --> 00:09:09,490 nested callbacks. 109 00:09:09,490 --> 00:09:15,970 So now if I run that and we see hello hi, the timer is done, we see done and we see done again because 110 00:09:15,970 --> 00:09:18,490 I'm calling fetch data twice. 111 00:09:18,490 --> 00:09:22,640 So this might be difficult to wrap your head around for the first time, 112 00:09:22,690 --> 00:09:26,460 we will reuse it throughout this course and then it will become clearer, 113 00:09:26,550 --> 00:09:35,800 again this code is mostly not written by you but it is a crucial concept that makes our async code more 114 00:09:35,890 --> 00:09:37,420 manageable. 115 00:09:37,420 --> 00:09:44,260 There also is another way of managing this, async await, two special keywords you can use in modern javascript 116 00:09:44,680 --> 00:09:46,990 and I'll have a separate section about this towards 117 00:09:47,050 --> 00:09:53,100 the end of the course. I don't want to introduce it here because it can actually be more confusing than this syntax 118 00:09:53,110 --> 00:09:58,540 here and I'll want to stick to this one to not introduce too many new features at the same time 119 00:09:58,540 --> 00:09:59,680 here. 120 00:09:59,680 --> 00:10:02,400 Async code is something you have to understand though 121 00:10:02,520 --> 00:10:07,510 and if it's not totally clear by now, that is fine though, you will see it throughout the course 122 00:10:07,510 --> 00:10:08,250 a bunch 123 00:10:08,320 --> 00:10:14,870 because we have a lot of asynchronous events in nodejs and I will explain this multiple times, 124 00:10:14,950 --> 00:10:17,370 I'll also explain promises again, 125 00:10:17,380 --> 00:10:23,410 I just want to ensure that you have seen this by now and that you then have a chance of understanding 126 00:10:23,410 --> 00:10:26,260 this, how it works and how we deal with it.