1 00:00:01,830 --> 00:00:03,030 Welcome back! 2 00:00:03,030 --> 00:00:06,790 In this video, we're gonna read files and write two files 3 00:00:06,790 --> 00:00:11,063 just like before, but instead in an asynchronous way. 4 00:00:13,160 --> 00:00:14,960 Let's add some comments here before. 5 00:00:19,630 --> 00:00:21,183 So, this is the blocking, 6 00:00:26,160 --> 00:00:31,160 synchronous way, and then, we will do an exercise 7 00:00:32,870 --> 00:00:36,480 in an non-blocking, asynchronous way. 8 00:00:36,480 --> 00:00:38,230 So, we're not gonna do the same thing, 9 00:00:38,230 --> 00:00:40,300 we're just gonna invent some other 10 00:00:40,300 --> 00:00:43,150 kind of crazy exercise here. 11 00:00:43,150 --> 00:00:46,350 So, to read a file in an asynchronous way, 12 00:00:46,350 --> 00:00:48,410 it works like this. 13 00:00:48,410 --> 00:00:53,380 Again, we need the FS module, and then read file, 14 00:00:54,890 --> 00:00:57,920 but this time, not read file sync, of course. 15 00:00:57,920 --> 00:01:01,930 And, again, we pass in the name of the file, 16 00:01:01,930 --> 00:01:04,060 or the path to the file actually, 17 00:01:04,060 --> 00:01:07,360 and so again, it is txt, 18 00:01:07,360 --> 00:01:11,583 and the file that I want right now is called start.txt, 19 00:01:12,460 --> 00:01:14,603 so this one. 20 00:01:16,040 --> 00:01:17,860 Oops, sorry for that. 21 00:01:17,860 --> 00:01:21,790 So, this is the file that I want, on the task is read this, 22 00:01:21,790 --> 00:01:24,660 and I'm gonna explain to you why a bit later. 23 00:01:24,660 --> 00:01:26,860 For now, don't worry about the content here. 24 00:01:28,220 --> 00:01:29,360 So, in the read file, 25 00:01:29,360 --> 00:01:34,360 we actually do not have to specify the file encoding, okay. 26 00:01:34,580 --> 00:01:36,090 And so, the next parameter, 27 00:01:36,090 --> 00:01:39,500 the second one will be a callback function, 28 00:01:39,500 --> 00:01:42,270 and that is what we learned in the last lecture. 29 00:01:42,270 --> 00:01:45,380 So, Node JS is all built around callbacks 30 00:01:45,380 --> 00:01:48,750 in order to implement an asynchronous behavior, 31 00:01:48,750 --> 00:01:50,200 and this is how it works. 32 00:01:50,200 --> 00:01:53,080 So, Node will start reading this file here 33 00:01:53,080 --> 00:01:56,470 in the background, and as soon as it is ready, 34 00:01:56,470 --> 00:02:00,543 it will start the callback function that we specify here. 35 00:02:03,880 --> 00:02:06,730 Okay, and it calls this callback function 36 00:02:06,730 --> 00:02:08,450 with two arguments. 37 00:02:08,450 --> 00:02:11,440 The first one is the error, 38 00:02:11,440 --> 00:02:15,560 and the second one is the actual data, okay? 39 00:02:15,560 --> 00:02:19,130 So, this error first callback style is 40 00:02:19,130 --> 00:02:22,090 very typical in Node JS, okay. 41 00:02:22,090 --> 00:02:24,910 So, many, many times, the first parameter 42 00:02:24,910 --> 00:02:28,730 in a callback will be the error, in case there was any, 43 00:02:28,730 --> 00:02:33,060 and the second one will then be the data, itself. 44 00:02:33,060 --> 00:02:34,403 What matters here is 45 00:02:34,403 --> 00:02:38,610 that the error is usually always the first one, okay? 46 00:02:38,610 --> 00:02:41,740 And so just to test it out for now, 47 00:02:41,740 --> 00:02:46,740 let's simply log through console, the data. 48 00:02:47,100 --> 00:02:50,050 And so, let's now actually test that. 49 00:02:50,050 --> 00:02:51,520 But, before we do this, 50 00:02:51,520 --> 00:02:55,793 let us actually still specify the filing coding here, okay? 51 00:02:57,820 --> 00:03:00,160 So, I'm not one hundred percent sure 52 00:03:00,160 --> 00:03:01,933 that it works without this, 53 00:03:04,190 --> 00:03:09,190 so clean this now, run it again, and here we see read this. 54 00:03:10,400 --> 00:03:13,790 So, let's analyze, again, what happened here. 55 00:03:13,790 --> 00:03:17,260 As soon as this function here is run, 56 00:03:17,260 --> 00:03:20,980 it will start reading this file in the background 57 00:03:20,980 --> 00:03:24,083 without blocking the rest of the code execution. 58 00:03:24,970 --> 00:03:27,663 So, let me actually demonstrate this here. 59 00:03:29,290 --> 00:03:30,690 So, a console.log 60 00:03:33,370 --> 00:03:38,370 will read file, and just to have a bit less confusion there, 61 00:03:38,530 --> 00:03:43,170 let me comment out this part here, okay. 62 00:03:43,170 --> 00:03:45,970 And so, what do you think will happen now? 63 00:03:45,970 --> 00:03:48,533 What log are we gonna see first? 64 00:03:51,830 --> 00:03:55,060 And indeed, first we see will read file, 65 00:03:55,060 --> 00:03:58,470 and, only then, we see read this. 66 00:03:58,470 --> 00:04:00,960 So, again, why did that happen? 67 00:04:00,960 --> 00:04:04,400 So, as I mentioned Node JS will start reading the file 68 00:04:04,400 --> 00:04:07,570 in the background here, and will not block the code, 69 00:04:07,570 --> 00:04:11,760 and will then immediately move on to the next line of code. 70 00:04:11,760 --> 00:04:15,240 And, the next line of code, well, it's this log here, 71 00:04:15,240 --> 00:04:17,030 and so that is the first thing 72 00:04:17,030 --> 00:04:19,520 that will be logged here to the terminal. 73 00:04:19,520 --> 00:04:22,760 Only then, when a file is completely read, 74 00:04:22,760 --> 00:04:26,580 this callback function here will run, okay? 75 00:04:26,580 --> 00:04:30,810 And again, this callback function has access to the error 76 00:04:30,810 --> 00:04:33,070 and the data that was read, 77 00:04:33,070 --> 00:04:36,260 and we could really call this here anything that we wanted. 78 00:04:36,260 --> 00:04:39,250 We could call it text as well, it doesn't really matter, 79 00:04:39,250 --> 00:04:42,240 all that matters is that it is the second argument 80 00:04:42,240 --> 00:04:43,713 in this callback function. 81 00:04:44,670 --> 00:04:47,070 Let's actually go back to data 82 00:04:47,070 --> 00:04:49,740 because I like that way better. 83 00:04:49,740 --> 00:04:54,740 And so, only then, this console.log will run with the data, 84 00:04:54,900 --> 00:04:57,510 so with the text that was in the file. 85 00:04:57,510 --> 00:05:01,480 And so, that's why we see this here as the second log. 86 00:05:01,480 --> 00:05:04,430 All right, now to take it even further, 87 00:05:04,430 --> 00:05:08,860 let's actually do another read file, but instead of this, 88 00:05:08,860 --> 00:05:11,990 so that I can show you we can basically do 89 00:05:11,990 --> 00:05:16,130 multiple steps, one after the other, with callbacks. 90 00:05:16,130 --> 00:05:20,810 So, steps that depend upon the result of the previous step. 91 00:05:20,810 --> 00:05:25,310 Okay, so that's why actually in the start file, 92 00:05:25,310 --> 00:05:26,610 I have read this 93 00:05:26,610 --> 00:05:29,930 because then there is a file called read this, 94 00:05:29,930 --> 00:05:33,103 which has the content that we're actually interested in. 95 00:05:34,090 --> 00:05:34,923 Okay? 96 00:05:37,060 --> 00:05:39,963 So, what I'm gonna to do here is to copy this code, 97 00:05:40,890 --> 00:05:42,793 and put it in here. 98 00:05:44,740 --> 00:05:48,210 I'm gonna call this one data one, and then data two, 99 00:05:48,210 --> 00:05:52,900 and the result of the second step, so the second file read, 100 00:05:52,900 --> 00:05:55,140 will depend on the first one. 101 00:05:55,140 --> 00:06:00,140 That's because we will use the data for file name, remember? 102 00:06:02,030 --> 00:06:05,340 So, here we are doing a (mumbles) now 103 00:06:06,290 --> 00:06:10,730 because we need to put in that variable, and it is called 104 00:06:14,490 --> 00:06:15,323 data one. 105 00:06:16,330 --> 00:06:18,290 Okay, make sense? 106 00:06:18,290 --> 00:06:22,900 So, data one will be read this, okay, 107 00:06:22,900 --> 00:06:27,900 and so then, in the next step, we read txt/readthis.txt, 108 00:06:30,090 --> 00:06:31,910 which is then this. 109 00:06:31,910 --> 00:06:35,110 Okay, and so that's why this file name here is 110 00:06:35,110 --> 00:06:37,053 the same as this content. 111 00:06:39,340 --> 00:06:42,283 And so, that's logged through console data to that. 112 00:06:43,310 --> 00:06:45,833 And, let's quickly test if this works, 113 00:06:48,370 --> 00:06:53,370 and indeed, so that is the content of read this.txt. 114 00:06:53,860 --> 00:06:57,030 And, now I'm actually gonna take it one step further even 115 00:06:57,030 --> 00:07:00,740 because there's some other text in this append file 116 00:07:00,740 --> 00:07:04,080 that I want to add to this first string, 117 00:07:04,080 --> 00:07:06,420 so there's text coming from the other file. 118 00:07:06,420 --> 00:07:08,590 And so, we have yet another step 119 00:07:08,590 --> 00:07:10,840 that depends on the previous step, 120 00:07:10,840 --> 00:07:14,563 so what I'm gonna do is to add another read file in here. 121 00:07:15,560 --> 00:07:17,660 So, just like this. 122 00:07:17,660 --> 00:07:19,313 So, this one is called append, 123 00:07:21,610 --> 00:07:26,610 and I'm gonna call this one the data three, data three here, 124 00:07:27,720 --> 00:07:30,133 and so that's, again, run that. 125 00:07:32,760 --> 00:07:37,570 And, okay, so now we have these two results here. 126 00:07:37,570 --> 00:07:40,830 All right, and now finally, as the last step, 127 00:07:40,830 --> 00:07:44,030 I want to write these two strings together 128 00:07:44,030 --> 00:07:46,360 into a file, okay? 129 00:07:46,360 --> 00:07:48,500 So far, we have only read files, 130 00:07:48,500 --> 00:07:51,160 but I want to write a file as well, 131 00:07:51,160 --> 00:07:53,730 so let's do that right here as well. 132 00:07:53,730 --> 00:07:54,623 So, fs.writeFile, 133 00:07:57,480 --> 00:08:01,100 and of course, we're not using the synchronous one 134 00:08:01,100 --> 00:08:02,140 like we did before, 135 00:08:02,140 --> 00:08:06,320 but again we use, just like here and here and here, 136 00:08:06,320 --> 00:08:10,113 we use the asynchronous version, not the synchronous one. 137 00:08:11,600 --> 00:08:16,600 So, txt slash, missing this one here, 138 00:08:19,240 --> 00:08:20,143 final. 139 00:08:22,314 --> 00:08:25,933 Then, we should add the texting coding here as well, 140 00:08:29,650 --> 00:08:33,040 and then this one also accepts a callback function, 141 00:08:33,040 --> 00:08:36,220 but in this case there is no data that we read, 142 00:08:36,220 --> 00:08:38,370 and so, we don't need two arguments. 143 00:08:38,370 --> 00:08:41,933 So, the only argument that we have is the error, actually. 144 00:08:44,100 --> 00:08:48,980 Okay, so here we have the error, and the data that was read, 145 00:08:48,980 --> 00:08:52,270 but here in writeFile, there is no data. 146 00:08:52,270 --> 00:08:56,690 All that there is, or can be, is an error, okay? 147 00:08:56,690 --> 00:08:58,530 And actually, we're missing something here, 148 00:08:58,530 --> 00:09:03,063 which is what we actually want to write to the file. 149 00:09:03,910 --> 00:09:06,430 Okay, and so that is the second argument, 150 00:09:06,430 --> 00:09:11,100 and what that is, is data two and data three. 151 00:09:11,100 --> 00:09:12,823 So, again a (mumbles) string here, 152 00:09:14,340 --> 00:09:16,063 data two, 153 00:09:17,620 --> 00:09:21,323 then a new line character, which again, is backslash n, 154 00:09:23,010 --> 00:09:25,523 and then data 3. 155 00:09:27,360 --> 00:09:32,010 All right, and so, just like with the read file functions, 156 00:09:32,010 --> 00:09:35,800 then this callback is what's run at the end, 157 00:09:35,800 --> 00:09:38,660 so what I'm gonna do here is to simply log through console 158 00:09:38,660 --> 00:09:40,613 that the files have been written, 159 00:09:41,490 --> 00:09:43,190 or that the file has been written. 160 00:09:44,430 --> 00:09:49,360 Your file has been written, 161 00:09:49,360 --> 00:09:53,220 and let's just use some fun emoji here, 162 00:09:53,220 --> 00:09:56,883 just to make the console a bit brighter for us, 163 00:09:58,300 --> 00:10:03,080 and I think we should be done like this. 164 00:10:03,080 --> 00:10:06,023 So, let's clear the console one more time, run it, 165 00:10:07,370 --> 00:10:10,560 and indeed we see your file has been written. 166 00:10:10,560 --> 00:10:11,833 So, has it really? 167 00:10:13,460 --> 00:10:14,990 Final. 168 00:10:14,990 --> 00:10:16,433 Oh, yeah, here it is. 169 00:10:18,140 --> 00:10:22,040 So, that is the read this text, 170 00:10:22,040 --> 00:10:27,040 and the append text, both together, both in the same file. 171 00:10:27,490 --> 00:10:32,490 Okay, so that is how we perform multiple steps in orders, 172 00:10:33,160 --> 00:10:36,270 using callback functions, right? 173 00:10:36,270 --> 00:10:40,180 Because imagine that you simply did the same file read, 174 00:10:40,180 --> 00:10:42,490 and then the second file read, so this one, 175 00:10:42,490 --> 00:10:44,060 right after that. 176 00:10:44,060 --> 00:10:46,770 Well, how would you then get access to the data 177 00:10:46,770 --> 00:10:49,200 from the first one, right? 178 00:10:49,200 --> 00:10:52,420 And so, that is how this pattern emerges. 179 00:10:52,420 --> 00:10:53,720 It actually has it's own name, 180 00:10:53,720 --> 00:10:55,930 and I think I mentioned that in the last video, 181 00:10:55,930 --> 00:10:58,240 it is the called callback hell, 182 00:10:58,240 --> 00:11:01,490 and there are some solutions to make this code here 183 00:11:01,490 --> 00:11:04,080 more readable and better to understand, 184 00:11:04,080 --> 00:11:07,130 but for now, that doesn't matter at all for you. 185 00:11:07,130 --> 00:11:10,650 What matters is that Node JS is built around 186 00:11:10,650 --> 00:11:13,480 this philosophy of callbacks, 187 00:11:13,480 --> 00:11:17,530 so that is how Node JS implements asynchronous operations, 188 00:11:17,530 --> 00:11:20,330 by calling callbacks as soon as the operation 189 00:11:20,330 --> 00:11:23,260 that it's doing has been finished. 190 00:11:23,260 --> 00:11:26,280 And, by the way, this way of writing function 191 00:11:26,280 --> 00:11:28,110 that you see here, again, 192 00:11:28,110 --> 00:11:29,870 in case you're not familiar with it, 193 00:11:29,870 --> 00:11:33,420 it is the new ES6 syntax as well, okay? 194 00:11:33,420 --> 00:11:36,320 So, again, I hope that you are familiar 195 00:11:36,320 --> 00:11:38,550 with ES6 at this point, 196 00:11:38,550 --> 00:11:41,950 and so that all of this makes complete sense to you. 197 00:11:41,950 --> 00:11:44,580 If you were to write this function here 198 00:11:45,700 --> 00:11:49,461 without the error function syntax, we would do 199 00:11:49,461 --> 00:11:54,461 simply like this, function, err, data one, 200 00:11:55,950 --> 00:11:57,600 and then like this. 201 00:11:57,600 --> 00:11:59,470 So, that is a normal function, 202 00:11:59,470 --> 00:12:02,210 let's say an old-fashioned function, 203 00:12:02,210 --> 00:12:05,470 and the new version works like this. 204 00:12:05,470 --> 00:12:09,490 The difference between them is mainly the syntax, 205 00:12:09,490 --> 00:12:12,690 but also the fact that an error function, 206 00:12:12,690 --> 00:12:14,360 so this kind of function, 207 00:12:14,360 --> 00:12:17,070 doesn't get it's own disk keyword, 208 00:12:17,070 --> 00:12:20,860 so it uses the disk keyword from the parent function. 209 00:12:20,860 --> 00:12:24,540 And, that is called the lexical disk keyword, 210 00:12:24,540 --> 00:12:27,500 while a normal function like this one always gets 211 00:12:27,500 --> 00:12:30,920 its own disk keyword, right? 212 00:12:30,920 --> 00:12:33,610 I'm sure you're familiar with that kind of stuff, 213 00:12:33,610 --> 00:12:37,640 but just doing a small review here in case you're not. 214 00:12:37,640 --> 00:12:39,673 Okay, I hope that made since. 215 00:12:40,600 --> 00:12:44,150 We did actually never use this error, 216 00:12:44,150 --> 00:12:46,160 we didn't handle any errors, 217 00:12:46,160 --> 00:12:50,060 so, for example, imagine that this file here did not exist. 218 00:12:50,060 --> 00:12:52,490 Well we could have used this error, 219 00:12:52,490 --> 00:12:56,300 and let's actually do that, but just for this one here, 220 00:12:56,300 --> 00:13:00,820 so I don't wanna create all of these error handlers here, 221 00:13:00,820 --> 00:13:04,100 but just in this situation, let's say there was an error, 222 00:13:04,100 --> 00:13:06,463 and so let's say if error, 223 00:13:07,340 --> 00:13:10,373 the return from this function, so do nothing else, 224 00:13:12,290 --> 00:13:13,743 and log to the console, 225 00:13:18,050 --> 00:13:22,260 error, and then we can add some other emoji here, 226 00:13:22,260 --> 00:13:25,653 like this explosion, so like something exploded here. 227 00:13:28,010 --> 00:13:32,933 So, let's now change this here, like start.txt, 228 00:13:33,900 --> 00:13:34,973 run this again, 229 00:13:36,090 --> 00:13:39,980 and so, we have this error now, 230 00:13:39,980 --> 00:13:42,570 so it gives us this log to the console, 231 00:13:42,570 --> 00:13:46,200 and since we did return, it will not do anything after that, 232 00:13:46,200 --> 00:13:49,990 so all of this is basically ignored and will not run, 233 00:13:49,990 --> 00:13:51,823 which is exactly what we want. 234 00:13:52,680 --> 00:13:55,863 Right, but if we put it back to normal, 235 00:13:57,720 --> 00:13:59,090 and then run it again, 236 00:13:59,090 --> 00:14:02,010 well then, everything works just like before. 237 00:14:02,010 --> 00:14:05,270 So, get used to this pattern of callbacks 238 00:14:05,270 --> 00:14:08,270 because you will see it all over the place in Node JS 239 00:14:08,270 --> 00:14:10,163 and throughout this section.