WEBVTT

1
00:00:01.470 --> 00:00:03.930
<v Jonas>So, now that you're super comfortable</v>

2
00:00:03.930 --> 00:00:08.130
with consuming promises and also building promises,

3
00:00:08.130 --> 00:00:10.170
let's turn our attention back

4
00:00:10.170 --> 00:00:13.050
to actually consuming promises.

5
00:00:13.050 --> 00:00:16.380
That's because since ES 2017,

6
00:00:16.380 --> 00:00:18.060
there is now an even better

7
00:00:18.060 --> 00:00:21.120
and easier way to consume promises,

8
00:00:21.120 --> 00:00:23.463
which is called async/await.

9
00:00:25.200 --> 00:00:27.870
So let me show you how it works.

10
00:00:27.870 --> 00:00:31.140
So we start by creating a special kind of function,

11
00:00:31.140 --> 00:00:33.303
which is an async function.

12
00:00:35.310 --> 00:00:38.370
So in this lecture, we will basically recreate

13
00:00:38.370 --> 00:00:41.343
the whereAmI function that we have been building.

14
00:00:42.675 --> 00:00:43.508
whereAmI,

15
00:00:45.476 --> 00:00:46.920
and so function,

16
00:00:46.920 --> 00:00:50.740
but for now, we will pass in the country again

17
00:00:51.630 --> 00:00:54.030
to make it simple at the beginning.

18
00:00:54.030 --> 00:00:55.260
But as I was saying,

19
00:00:55.260 --> 00:00:58.530
we now need to make this a special kind of function,

20
00:00:58.530 --> 00:01:00.960
which is an async function.

21
00:01:00.960 --> 00:01:04.290
And we do this by simply adding async

22
00:01:04.290 --> 00:01:06.990
here in front of the function.

23
00:01:06.990 --> 00:01:10.590
And so this function is now an asynchronous function.

24
00:01:10.590 --> 00:01:13.380
So a function that will basically keep running

25
00:01:13.380 --> 00:01:16.560
in the background while performing the code

26
00:01:16.560 --> 00:01:18.330
that's inside of it.

27
00:01:18.330 --> 00:01:20.400
Then, when this function is done,

28
00:01:20.400 --> 00:01:22.950
it automatically returns a promise.

29
00:01:22.950 --> 00:01:26.220
But more on that in the next video.

30
00:01:26.220 --> 00:01:30.570
For now, what's important is that inside an async function,

31
00:01:30.570 --> 00:01:33.693
we can have one or more await statements.

32
00:01:35.130 --> 00:01:36.780
So, await,

33
00:01:36.780 --> 00:01:39.240
and then here, we need a promise.

34
00:01:39.240 --> 00:01:40.890
And so we can use the promise

35
00:01:40.890 --> 00:01:43.443
returned from the fetch function.

36
00:01:44.370 --> 00:01:46.770
And so let's now use our API again

37
00:01:46.770 --> 00:01:49.503
to search for a country, basically.

38
00:01:50.760 --> 00:01:54.780
So let's see where we have some information about that.

39
00:01:54.780 --> 00:01:56.580
And here we go.

40
00:01:56.580 --> 00:01:59.673
So this is the URL that we have been using.

41
00:02:00.600 --> 00:02:03.753
So make sure you grab it somewhere from your code.

42
00:02:05.100 --> 00:02:07.923
And so here, let's now pass in this country again.

43
00:02:09.300 --> 00:02:10.620
All right.

44
00:02:10.620 --> 00:02:13.830
So, again, this year, we'll return a promise,

45
00:02:13.830 --> 00:02:16.710
and so in an async function like this one,

46
00:02:16.710 --> 00:02:18.780
we can use the await keyword

47
00:02:18.780 --> 00:02:23.070
to basically await for the result of this promise.

48
00:02:23.070 --> 00:02:26.790
So, basically, await will stop the code execution

49
00:02:26.790 --> 00:02:28.800
at this point of the function

50
00:02:28.800 --> 00:02:31.290
until the promise is fulfilled.

51
00:02:31.290 --> 00:02:34.983
And so, until the data has been fetched, in this case.

52
00:02:36.390 --> 00:02:38.640
But now, after that explanation,

53
00:02:38.640 --> 00:02:41.640
you might think, "Isn't stopping the code,

54
00:02:41.640 --> 00:02:44.040
blocking the execution?"

55
00:02:44.040 --> 00:02:47.100
Well, that's a really good question,

56
00:02:47.100 --> 00:02:50.460
but the answer is actually no, in this case.

57
00:02:50.460 --> 00:02:54.360
Because stopping execution in an async function,

58
00:02:54.360 --> 00:02:56.130
which is what we have here,

59
00:02:56.130 --> 00:02:58.410
is actually not a problem

60
00:02:58.410 --> 00:03:01.640
because this function is running asynchronously

61
00:03:01.640 --> 00:03:03.180
in the background.

62
00:03:03.180 --> 00:03:04.380
And so, therefore,

63
00:03:04.380 --> 00:03:08.400
it is not blocking the main thread of execution.

64
00:03:08.400 --> 00:03:11.190
So, it's not blocking the call stack.

65
00:03:11.190 --> 00:03:16.080
And in fact, that's what's so special about async/await.

66
00:03:16.080 --> 00:03:18.630
So it's the fact that it makes our code

67
00:03:18.630 --> 00:03:21.420
look like regular synchronous code,

68
00:03:21.420 --> 00:03:26.420
while behind the scenes, everything is in fact asynchronous.

69
00:03:26.700 --> 00:03:28.170
All right.

70
00:03:28.170 --> 00:03:33.170
But, anyway, as soon as this promise here is resolved,

71
00:03:33.240 --> 00:03:36.090
then the value of this whole await expression

72
00:03:36.090 --> 00:03:38.160
that we have here is going to be

73
00:03:38.160 --> 00:03:41.190
the resolved value of the promise.

74
00:03:41.190 --> 00:03:44.583
And so we can simply store that into a variable.

75
00:03:46.290 --> 00:03:50.640
So let's call it res for response.

76
00:03:50.640 --> 00:03:54.840
And then, here, we can take a look at that response.

77
00:03:54.840 --> 00:03:57.870
And just to show you that this function here

78
00:03:57.870 --> 00:04:00.120
is actually asynchronous,

79
00:04:00.120 --> 00:04:03.153
let's log something to the console before we call it.

80
00:04:05.220 --> 00:04:09.780
So just first, because this should be printed first, right?

81
00:04:09.780 --> 00:04:12.633
And then, or actually, we should call the function first.

82
00:04:13.727 --> 00:04:16.533
So whereAmI with Portugal.

83
00:04:18.420 --> 00:04:19.893
But even by doing this,

84
00:04:21.060 --> 00:04:24.540
this console.log('FIRST') will be displayed first.

85
00:04:24.540 --> 00:04:27.360
Because, again, this is an async function,

86
00:04:27.360 --> 00:04:29.580
and so once the function is called,

87
00:04:29.580 --> 00:04:32.460
it is then loaded off to the background.

88
00:04:32.460 --> 00:04:35.760
And so this fetch here will be running in the background

89
00:04:35.760 --> 00:04:37.890
without blocking our main thread.

90
00:04:37.890 --> 00:04:40.590
And so the code will move on to the next line,

91
00:04:40.590 --> 00:04:42.867
which is then this console.log('FIRST').

92
00:04:44.490 --> 00:04:46.080
All right.

93
00:04:46.080 --> 00:04:51.080
And so, indeed, we got the FIRST printed first,

94
00:04:51.300 --> 00:04:54.120
and then here we got the response.

95
00:04:54.120 --> 00:04:56.580
But this time, we got this response

96
00:04:56.580 --> 00:04:59.193
in this really nice and elegant way.

97
00:05:00.120 --> 00:05:03.630
So you see here that by using async/await,

98
00:05:03.630 --> 00:05:06.030
our asynchronous code here

99
00:05:06.030 --> 00:05:09.810
really looks and feels like synchronous code.

100
00:05:09.810 --> 00:05:12.840
So we can simply await until the value

101
00:05:12.840 --> 00:05:15.720
of the promise is returned, basically,

102
00:05:15.720 --> 00:05:19.290
and then just assign that value to a variable.

103
00:05:19.290 --> 00:05:22.470
And that is something that was impossible before.

104
00:05:22.470 --> 00:05:25.140
So before we had to mess with callback functions,

105
00:05:25.140 --> 00:05:28.020
and that was true in callback hell,

106
00:05:28.020 --> 00:05:31.770
but also by consuming promises with the then method.

107
00:05:31.770 --> 00:05:33.600
But now with the async/await,

108
00:05:33.600 --> 00:05:36.450
that is just completely gone, right?

109
00:05:36.450 --> 00:05:40.230
So again, this looks now like normal synchronous code,

110
00:05:40.230 --> 00:05:43.560
where we simply assign values to a variable.

111
00:05:43.560 --> 00:05:45.720
And that makes it so much easier

112
00:05:45.720 --> 00:05:48.870
and more clean in my opinion.

113
00:05:48.870 --> 00:05:52.680
Now, before you start using async/await all over the place,

114
00:05:52.680 --> 00:05:55.950
you need to first understand that async/await

115
00:05:55.950 --> 00:05:59.010
is in fact simply syntactic sugar

116
00:05:59.010 --> 00:06:01.980
over the then method in promises.

117
00:06:01.980 --> 00:06:03.720
So, of course, behind the scenes,

118
00:06:03.720 --> 00:06:06.060
we are still using promises,

119
00:06:06.060 --> 00:06:08.370
we are simply using a different way

120
00:06:08.370 --> 00:06:12.000
of consuming them here in this case.

121
00:06:12.000 --> 00:06:14.970
But what we have here, so this,

122
00:06:14.970 --> 00:06:17.220
is essentially exactly the same

123
00:06:17.220 --> 00:06:21.210
as doing it the old way, basically.

124
00:06:21.210 --> 00:06:23.523
So using then and then res,

125
00:06:24.660 --> 00:06:28.803
and then console.log(res), like we did here.

126
00:06:29.850 --> 00:06:31.863
So this is exactly the same.

127
00:06:34.080 --> 00:06:35.403
So let's put that here,

128
00:06:37.530 --> 00:06:40.290
and comment it out, of course.

129
00:06:40.290 --> 00:06:41.940
Because what we are interested in

130
00:06:41.940 --> 00:06:44.493
is indeed async/await right now.

131
00:06:45.690 --> 00:06:48.960
So now that we know how async/await works,

132
00:06:48.960 --> 00:06:52.710
it's time to actually recreate the whereAmI function.

133
00:06:52.710 --> 00:06:55.440
So first off, we need to get the JSON

134
00:06:55.440 --> 00:06:59.283
out of this response, right?

135
00:07:00.120 --> 00:07:02.310
And so, remember, on the response,

136
00:07:02.310 --> 00:07:04.353
we need to call a JSON.

137
00:07:05.250 --> 00:07:09.090
And remember that this itself returns a new promise.

138
00:07:09.090 --> 00:07:12.390
And so previously, we would have to return this promise

139
00:07:12.390 --> 00:07:15.030
and then chain another then handler.

140
00:07:15.030 --> 00:07:17.760
But now, this becomes so much easier.

141
00:07:17.760 --> 00:07:20.910
All we have to do is to, again, await this,

142
00:07:20.910 --> 00:07:23.910
and then we can store the results directly

143
00:07:23.910 --> 00:07:27.123
into the data variable that we have been using before.

144
00:07:30.180 --> 00:07:33.270
All right. And so, here it is.

145
00:07:33.270 --> 00:07:35.940
So here is the same data as before,

146
00:07:35.940 --> 00:07:38.223
and so now all we need to do is to render it.

147
00:07:39.480 --> 00:07:44.480
So render country and data at position zero.

148
00:07:45.090 --> 00:07:48.240
And in case you skipped any of the previous videos

149
00:07:48.240 --> 00:07:52.110
and don't have this render country function for some reason,

150
00:07:52.110 --> 00:07:56.370
you can simply get it from the final files of this section,

151
00:07:56.370 --> 00:07:58.290
from the GitHub repository.

152
00:07:58.290 --> 00:08:02.130
So from where you also got the starter files.

153
00:08:02.130 --> 00:08:03.420
Now okay.

154
00:08:03.420 --> 00:08:06.990
And, yeah, there is our data,

155
00:08:06.990 --> 00:08:09.750
so rendered to the page here.

156
00:08:09.750 --> 00:08:13.830
Great. And all without the chaining of promises

157
00:08:13.830 --> 00:08:15.810
like we had before.

158
00:08:15.810 --> 00:08:18.450
So this is really elegant, one more time,

159
00:08:18.450 --> 00:08:21.030
simply being able to essentially store

160
00:08:21.030 --> 00:08:25.410
the fulfilled promise value immediately into a variable

161
00:08:25.410 --> 00:08:28.530
without having to mess with callback functions.

162
00:08:28.530 --> 00:08:30.630
Now, okay. But now,

163
00:08:30.630 --> 00:08:33.660
let's actually finish the function here

164
00:08:33.660 --> 00:08:36.540
with all the other functionality as well.

165
00:08:36.540 --> 00:08:40.323
So with geolocation and also reverse geocoding.

166
00:08:41.220 --> 00:08:44.250
So for that, we need to get our promise

167
00:08:44.250 --> 00:08:47.223
that we built before for geolocation.

168
00:08:48.180 --> 00:08:53.180
So, this is the one here, so let's get it.

169
00:08:53.580 --> 00:08:58.580
And so, again, async/await is only about consuming promises.

170
00:08:59.430 --> 00:09:03.423
The way that we built them is not influenced in any way.

171
00:09:05.130 --> 00:09:06.090
All right.

172
00:09:06.090 --> 00:09:09.003
So this year is going to work the exact same way.

173
00:09:12.180 --> 00:09:14.523
And so let's do that here before.

174
00:09:18.030 --> 00:09:20.250
And so getPosition, remember,

175
00:09:20.250 --> 00:09:22.410
it doesn't need any arguments.

176
00:09:22.410 --> 00:09:26.940
And so, as you know, all we have to do is to now await this

177
00:09:26.940 --> 00:09:30.003
and then store the result into a variable.

178
00:09:30.900 --> 00:09:34.263
And just like before, let's simply destructure this.

179
00:09:36.180 --> 00:09:40.200
And in fact, let me get the code from before

180
00:09:40.200 --> 00:09:42.123
so we don't have to repeat everything.

181
00:09:43.050 --> 00:09:45.630
So that was this code.

182
00:09:45.630 --> 00:09:49.923
And we also need the reverse geocoding, right?

183
00:09:51.030 --> 00:09:53.970
So, let's paste all of that here.

184
00:09:57.570 --> 00:10:00.600
So, what we want here is to get the latitude

185
00:10:00.600 --> 00:10:03.963
and longitude from pos.coords.

186
00:10:05.790 --> 00:10:08.160
So probably, we should just call this here,

187
00:10:08.160 --> 00:10:10.113
first, the position.

188
00:10:11.160 --> 00:10:13.410
And then from pos.coords,

189
00:10:13.410 --> 00:10:18.240
we get the lat and longitude, just like before.

190
00:10:18.240 --> 00:10:20.730
And then, now, the next one.

191
00:10:20.730 --> 00:10:23.880
So now we can use these latitude and longitude

192
00:10:23.880 --> 00:10:28.507
and one more time plug them into this reverse geocoding API.

193
00:10:29.790 --> 00:10:32.670
And so now, again, it becomes a lot easier

194
00:10:32.670 --> 00:10:35.070
to basically chain promises,

195
00:10:35.070 --> 00:10:37.350
because we don't have to return anything,

196
00:10:37.350 --> 00:10:40.020
we don't have to create new then methods

197
00:10:40.020 --> 00:10:43.140
and we don't have to create new callback functions.

198
00:10:43.140 --> 00:10:46.380
So all we have to do is to await this

199
00:10:46.380 --> 00:10:51.380
and store the result into some variable.

200
00:10:51.540 --> 00:10:54.960
So res for response.

201
00:10:54.960 --> 00:10:56.250
But we already have that,

202
00:10:56.250 --> 00:10:59.523
so let's call it geo for geocoding.

203
00:11:01.999 --> 00:11:04.800
And so let's take a look at that,

204
00:11:04.800 --> 00:11:07.080
or actually, not yet,

205
00:11:07.080 --> 00:11:11.670
because remember that this is going to be just a response,

206
00:11:11.670 --> 00:11:13.983
and so we need to get the JSON from there.

207
00:11:15.780 --> 00:11:17.733
And yet another promise.

208
00:11:18.930 --> 00:11:23.403
But this is now so easy and so beautiful to handle.

209
00:11:25.590 --> 00:11:27.213
So again, dataGeo.

210
00:11:28.260 --> 00:11:31.800
Let's give it a save just to format it a little bit.

211
00:11:31.800 --> 00:11:33.543
And I will add some comments here.

212
00:11:35.940 --> 00:11:37.473
So geolocation.

213
00:11:38.340 --> 00:11:40.827
Then reverse geocoding.

214
00:11:44.670 --> 00:11:47.793
And then, country data.

215
00:11:50.370 --> 00:11:52.200
So just to make sure that it worked,

216
00:11:52.200 --> 00:11:55.533
let's take a look at dataGeo.

217
00:11:57.930 --> 00:11:59.490
And, yes,

218
00:11:59.490 --> 00:12:03.060
this is it, right?

219
00:12:03.060 --> 00:12:07.620
And so again, here at the country property, we got Portugal.

220
00:12:07.620 --> 00:12:11.313
And so now we can plug that into this URL.

221
00:12:12.300 --> 00:12:17.010
So that's going to be dataGeo.country.

222
00:12:17.010 --> 00:12:20.343
And so now we can eliminate the country from here.

223
00:12:21.870 --> 00:12:24.393
And we also don't need to pass it in anymore.

224
00:12:25.290 --> 00:12:27.960
And so, let's reload.

225
00:12:27.960 --> 00:12:31.620
And we still get the same data about Portugal

226
00:12:31.620 --> 00:12:35.820
because that is simply where I am right now located.

227
00:12:35.820 --> 00:12:37.620
But in case you're somewhere else,

228
00:12:37.620 --> 00:12:41.043
then you will now get the data about your own country.

229
00:12:41.880 --> 00:12:43.590
So let's just take a minute

230
00:12:43.590 --> 00:12:47.253
and appreciate how beautiful this data flow here is.

231
00:12:48.180 --> 00:12:51.210
Let me just put this comment out here

232
00:12:51.210 --> 00:12:54.533
so we don't clutter our async function, okay?

233
00:12:55.890 --> 00:13:00.890
And so we now have all of this in one nice async function

234
00:13:00.900 --> 00:13:02.670
that runs behind the scenes

235
00:13:02.670 --> 00:13:05.103
until everything here is finished.

236
00:13:06.060 --> 00:13:11.060
So, we are awaiting here 1, 2, 3, 4, 5 promises

237
00:13:11.130 --> 00:13:14.790
in a very easy way in code that now actually looks

238
00:13:14.790 --> 00:13:18.030
and feels like normal synchronous code.

239
00:13:18.030 --> 00:13:19.950
So, to me, personally,

240
00:13:19.950 --> 00:13:22.500
this async/await feature was really

241
00:13:22.500 --> 00:13:26.640
a huge, huge addition to the JavaScript language.

242
00:13:26.640 --> 00:13:28.920
Now, again, just keep in mind

243
00:13:28.920 --> 00:13:32.160
that async/await is just syntactic sugar

244
00:13:32.160 --> 00:13:34.410
over consuming promises.

245
00:13:34.410 --> 00:13:37.410
So it's a bit like classes in JavaScript,

246
00:13:37.410 --> 00:13:39.780
which also hides the true nature

247
00:13:39.780 --> 00:13:42.600
of how things work behind the scenes.

248
00:13:42.600 --> 00:13:45.240
But I think that's no problem,

249
00:13:45.240 --> 00:13:47.370
at least if you already know exactly

250
00:13:47.370 --> 00:13:50.550
how promises and asynchronous JavaScript

251
00:13:50.550 --> 00:13:53.280
actually do work behind the scenes.

252
00:13:53.280 --> 00:13:55.740
And we spent a lot of time in this section

253
00:13:55.740 --> 00:13:59.433
learning all that, and so I'm sure that you will be fine.

254
00:14:00.360 --> 00:14:03.930
Also, async/await is actually used a lot

255
00:14:03.930 --> 00:14:06.720
together with the more traditional then method

256
00:14:06.720 --> 00:14:10.443
of consuming promises, as we will see in the next video.

257
00:14:11.280 --> 00:14:13.950
Now, let me just show you something,

258
00:14:13.950 --> 00:14:17.220
which is when we reload too fast here,

259
00:14:17.220 --> 00:14:20.520
then we should get that same error as before

260
00:14:20.520 --> 00:14:23.400
from the reverse geocoding,

261
00:14:23.400 --> 00:14:27.447
where we can only do three requests per second

262
00:14:27.447 --> 00:14:29.193
or something like that.

263
00:14:31.470 --> 00:14:33.903
Well, I guess I'm not fast enough here.

264
00:14:37.277 --> 00:14:39.103
Oh, okay, but here we go.

265
00:14:40.650 --> 00:14:43.560
So here we have that 403 error.

266
00:14:43.560 --> 00:14:45.420
And so, with this error,

267
00:14:45.420 --> 00:14:48.660
our whole example here falls apart.

268
00:14:48.660 --> 00:14:52.020
So we get this cascade of errors here

269
00:14:52.020 --> 00:14:54.210
and nothing works anymore.

270
00:14:54.210 --> 00:14:57.060
And the reason for all of these errors here

271
00:14:57.060 --> 00:14:59.760
is because right now we actually don't have

272
00:14:59.760 --> 00:15:01.650
any error handling here.

273
00:15:01.650 --> 00:15:04.173
And so let's fix that in the next video.

