WEBVTT

1
00:00:01.110 --> 00:00:02.230
<v Jonas>At this point,</v>

2
00:00:02.230 --> 00:00:04.070
we have a pretty good idea

3
00:00:04.070 --> 00:00:08.200
of how to work with async/await, right?

4
00:00:08.200 --> 00:00:11.260
However, there is one important thing missing.

5
00:00:11.260 --> 00:00:14.920
So right now, it might still be a little bit unclear

6
00:00:14.920 --> 00:00:19.320
what an async function actually is and how it works.

7
00:00:19.320 --> 00:00:21.203
And so let's now fix that.

8
00:00:23.010 --> 00:00:25.220
So to understand a bit better,

9
00:00:25.220 --> 00:00:27.280
what's actually happening here.

10
00:00:27.280 --> 00:00:31.163
Let's start by adding some more console.logs here.

11
00:00:33.600 --> 00:00:38.600
So let's say, will get location.

12
00:00:38.890 --> 00:00:41.763
And then in the second one here, we will say,

13
00:00:45.050 --> 00:00:49.073
finished getting location.

14
00:00:50.380 --> 00:00:52.720
And if we check the result here, now,

15
00:00:52.720 --> 00:00:55.080
I hope that you already know

16
00:00:55.080 --> 00:00:58.370
what the order of the logs here will be.

17
00:00:58.370 --> 00:00:59.930
So let's see.

18
00:00:59.930 --> 00:01:00.770
And so indeed,

19
00:01:00.770 --> 00:01:05.110
immediately we get the first log then the second one.

20
00:01:05.110 --> 00:01:07.090
And of course only after that

21
00:01:07.090 --> 00:01:10.930
we get all the logs coming from the async function.

22
00:01:10.930 --> 00:01:11.800
So again,

23
00:01:11.800 --> 00:01:14.350
that's because this is an async function

24
00:01:14.350 --> 00:01:16.230
that runs in the background.

25
00:01:16.230 --> 00:01:18.770
And so JavaScript immediately moves on

26
00:01:18.770 --> 00:01:20.590
to the next line here.

27
00:01:20.590 --> 00:01:24.040
Now, if this was indeed a regular function

28
00:01:24.040 --> 00:01:27.570
and there would be a console.log in that regular function,

29
00:01:27.570 --> 00:01:32.040
then of course, that would appear here between one and two.

30
00:01:32.040 --> 00:01:36.170
Right? Well, let's call this three here, actually.

31
00:01:36.170 --> 00:01:39.180
So it will then appear between one and three,

32
00:01:39.180 --> 00:01:41.850
but in this case it's an async function,

33
00:01:41.850 --> 00:01:44.210
and so therefore it runs in the background

34
00:01:44.210 --> 00:01:46.053
until the results are there,

35
00:01:46.940 --> 00:01:47.773
all right.

36
00:01:47.773 --> 00:01:51.050
But now let's say that we wanted to return some data

37
00:01:51.050 --> 00:01:53.503
from this function, all right?

38
00:01:54.940 --> 00:01:58.513
So let's first get rid of all these console.logs here.

39
00:02:01.760 --> 00:02:03.963
Put this all a bit better together.

40
00:02:05.370 --> 00:02:09.390
And so here at the end let's now say we wanted to return

41
00:02:11.210 --> 00:02:16.210
a string like we had previously based on the geocoding data.

42
00:02:18.190 --> 00:02:21.060
So that data is in dataGeo

43
00:02:21.060 --> 00:02:23.530
and so let's say you are in

44
00:02:27.010 --> 00:02:28.530
dataGeo.city

45
00:02:30.820 --> 00:02:33.963
and then just quickly the country here as well.

46
00:02:37.240 --> 00:02:39.910
So we return this string here

47
00:02:39.910 --> 00:02:42.960
and so let's say we now want to get,

48
00:02:42.960 --> 00:02:45.090
of course that data out here.

49
00:02:45.090 --> 00:02:46.860
And so for now, let's pretend

50
00:02:46.860 --> 00:02:49.940
that this is simply a regular function

51
00:02:49.940 --> 00:02:51.693
and then we would do this,

52
00:02:53.380 --> 00:02:55.870
we would simply define a variable.

53
00:02:55.870 --> 00:02:59.290
Then there, we would store that returned value.

54
00:02:59.290 --> 00:03:01.490
And then here, we could take a look at that,

55
00:03:02.600 --> 00:03:06.470
but what do you think is going to happen here in this case?

56
00:03:06.470 --> 00:03:07.873
Well, let's see.

57
00:03:08.800 --> 00:03:12.860
And so the second thing that is logged to the console here

58
00:03:12.860 --> 00:03:14.880
is this promise.

59
00:03:14.880 --> 00:03:16.500
And remember that back then,

60
00:03:16.500 --> 00:03:19.870
when we first started to work with async/await,

61
00:03:19.870 --> 00:03:24.380
I told you that an async function always returns a promise.

62
00:03:24.380 --> 00:03:27.260
And so here is the proof for that.

63
00:03:27.260 --> 00:03:28.930
And if we think about this,

64
00:03:28.930 --> 00:03:32.500
then it actually makes sense that here we get a promise

65
00:03:32.500 --> 00:03:36.120
and not the value that we would like to get.

66
00:03:36.120 --> 00:03:38.223
So the string here, right?

67
00:03:39.310 --> 00:03:43.260
The reason for that is that at this point of the code,

68
00:03:43.260 --> 00:03:46.160
JavaScript has simply no way of knowing yet

69
00:03:46.160 --> 00:03:48.450
there's a string here that we want

70
00:03:48.450 --> 00:03:50.660
because the function is still running,

71
00:03:50.660 --> 00:03:54.190
but it is also not blocking the code out here.

72
00:03:54.190 --> 00:03:57.220
And so therefore again, at this point,

73
00:03:57.220 --> 00:03:59.090
JavaScript has no way of knowing

74
00:03:59.090 --> 00:04:01.890
what will be returned from this function.

75
00:04:01.890 --> 00:04:04.850
And so therefore all that this function does return

76
00:04:04.850 --> 00:04:06.670
is a promise.

77
00:04:06.670 --> 00:04:10.420
Now the value that we return from an async function,

78
00:04:10.420 --> 00:04:12.730
so again, that's this string here

79
00:04:12.730 --> 00:04:15.730
will become the fulfilled value of the promise

80
00:04:15.730 --> 00:04:18.380
that is returned by the function.

81
00:04:18.380 --> 00:04:21.140
And so that's important to understand.

82
00:04:21.140 --> 00:04:24.500
So again, this promise that we see down here,

83
00:04:24.500 --> 00:04:26.750
the fulfilled value of that promise

84
00:04:26.750 --> 00:04:29.270
is going to be this string here,

85
00:04:29.270 --> 00:04:31.850
because that is the value that we return

86
00:04:31.850 --> 00:04:33.780
from the async function

87
00:04:33.780 --> 00:04:36.700
while at least if there is no error here happening

88
00:04:36.700 --> 00:04:37.940
in the function,

89
00:04:37.940 --> 00:04:41.113
but for now, let's assume the success here again.

90
00:04:42.200 --> 00:04:46.400
So since we know that this here will return a promise,

91
00:04:46.400 --> 00:04:50.193
we also know how we can actually get the data that we want.

92
00:04:51.050 --> 00:04:54.400
So all we need to do instead of this here

93
00:04:55.960 --> 00:04:57.773
is simply, whereAmI,

94
00:05:00.280 --> 00:05:02.693
let's comment out these two,

95
00:05:04.190 --> 00:05:06.053
and so this will be our promise.

96
00:05:07.030 --> 00:05:08.680
Then just like before

97
00:05:08.680 --> 00:05:12.350
we can use the then method to get the fulfilled value

98
00:05:12.350 --> 00:05:13.393
of the promise.

99
00:05:14.390 --> 00:05:16.783
Let's call that one city now.

100
00:05:20.440 --> 00:05:21.610
All right?

101
00:05:21.610 --> 00:05:23.830
So we're using the exact same variable name

102
00:05:24.740 --> 00:05:26.210
like we did here,

103
00:05:26.210 --> 00:05:28.560
but of course this one here didn't work,

104
00:05:28.560 --> 00:05:30.910
but here it is going to work.

105
00:05:30.910 --> 00:05:34.290
Because again, in the then handler,

106
00:05:34.290 --> 00:05:37.820
this argument that will be passed into the callback function

107
00:05:37.820 --> 00:05:41.420
is going to be the result value of the promise.

108
00:05:41.420 --> 00:05:43.000
And so one more time,

109
00:05:43.000 --> 00:05:45.930
that is this string here that is returned

110
00:05:45.930 --> 00:05:48.130
from the async function.

111
00:05:48.130 --> 00:05:51.283
And so now let's see what happens.

112
00:05:53.330 --> 00:05:55.110
Let's wait for it.

113
00:05:55.110 --> 00:06:00.093
Now we get our result, you are in Olhao, Portugal.

114
00:06:02.020 --> 00:06:02.970
And so with this,

115
00:06:02.970 --> 00:06:06.200
we essentially, successfully returned a value

116
00:06:06.200 --> 00:06:07.920
from the function.

117
00:06:07.920 --> 00:06:10.580
Now we will be able to do a little bit better,

118
00:06:10.580 --> 00:06:13.680
but for now let's think about errors.

119
00:06:13.680 --> 00:06:17.820
So if any error occurs here in this try block,

120
00:06:17.820 --> 00:06:20.620
then this return here will never be reached

121
00:06:20.620 --> 00:06:22.900
because the code will immediately jump

122
00:06:22.900 --> 00:06:26.150
here to the catch block, right?

123
00:06:26.150 --> 00:06:30.570
So let's just try to create some error here.

124
00:06:30.570 --> 00:06:33.240
I will just change this one here,

125
00:06:33.240 --> 00:06:35.513
so now nothing will work,

126
00:06:37.010 --> 00:06:38.283
so let's wait for it.

127
00:06:39.730 --> 00:06:42.533
And so indeed, now we have an error.

128
00:06:43.660 --> 00:06:48.563
Now here we get undefined from line five, four, three.

129
00:06:49.820 --> 00:06:51.120
That's this one.

130
00:06:51.120 --> 00:06:54.840
And so indeed now nothing was returned from the function,

131
00:06:54.840 --> 00:06:56.063
we get undefined.

132
00:06:57.080 --> 00:07:01.193
Now what's interesting here is that the log still worked.

133
00:07:02.350 --> 00:07:03.600
This console.log here,

134
00:07:03.600 --> 00:07:07.330
which has now logging undefined here is still running,

135
00:07:07.330 --> 00:07:11.390
which means that this callback function is still running,

136
00:07:11.390 --> 00:07:14.230
which means that the then method was called,

137
00:07:14.230 --> 00:07:17.300
which in turn means that this promise here

138
00:07:17.300 --> 00:07:21.380
was actually fulfilled and not rejected.

139
00:07:21.380 --> 00:07:25.410
So even though there was an error in the async function,

140
00:07:25.410 --> 00:07:27.950
the promise that the async function returns

141
00:07:27.950 --> 00:07:32.410
is still fulfilled and not rejected, right?

142
00:07:32.410 --> 00:07:35.713
And in fact, if we add a catch handler here,

143
00:07:39.890 --> 00:07:41.473
then let's see what happens.

144
00:07:43.530 --> 00:07:46.363
So console.error,

145
00:07:49.500 --> 00:07:51.513
error.message,

146
00:07:52.820 --> 00:07:54.283
then our emoji here.

147
00:07:55.490 --> 00:07:57.593
And actually let's add a two here.

148
00:07:59.740 --> 00:08:02.303
So the sequence is kind of one, two, three,

149
00:08:04.120 --> 00:08:05.513
and let's do the same here.

150
00:08:11.470 --> 00:08:12.650
All right?

151
00:08:12.650 --> 00:08:16.600
And so we should still get the error from here

152
00:08:16.600 --> 00:08:18.360
and indeed we do,

153
00:08:18.360 --> 00:08:22.230
but still it is this callback here that is executed.

154
00:08:22.230 --> 00:08:27.030
So that's why we get two undefined and not the catch block.

155
00:08:27.030 --> 00:08:27.890
And so again,

156
00:08:27.890 --> 00:08:30.920
what that means is that even though there was an error

157
00:08:30.920 --> 00:08:32.810
in the async function,

158
00:08:32.810 --> 00:08:36.250
the promise that it returns is still fulfilled.

159
00:08:36.250 --> 00:08:38.840
Now, if we wanted to fix that,

160
00:08:38.840 --> 00:08:42.520
if we want to be able to catch that error here as well,

161
00:08:42.520 --> 00:08:46.373
then we would have to rethrow that error right here.

162
00:08:47.500 --> 00:08:49.760
Rethrowing the error means to basically

163
00:08:49.760 --> 00:08:54.380
throw the error again so that we can then propagate it down.

164
00:08:54.380 --> 00:08:56.897
And so with that, we will manually reject a promise

165
00:08:56.897 --> 00:08:59.473
that's returned from the async function.

166
00:09:00.890 --> 00:09:05.890
So let's say reject promise returned from async function.

167
00:09:10.210 --> 00:09:14.303
So here we can now take the error and throw it again.

168
00:09:15.400 --> 00:09:16.723
So throw error,

169
00:09:18.080 --> 00:09:22.980
and so now we get the same error here as we had here.

170
00:09:22.980 --> 00:09:26.510
So again, it's, cannot read property flag of undefined

171
00:09:26.510 --> 00:09:29.180
and here the same and with this too.

172
00:09:29.180 --> 00:09:30.853
So it just coming from here.

173
00:09:31.790 --> 00:09:34.830
And so sometimes it's important to do this.

174
00:09:34.830 --> 00:09:38.350
And so rethrowing an error is then the correct solution

175
00:09:38.350 --> 00:09:41.310
to that problem, all right?

176
00:09:41.310 --> 00:09:45.520
And now finally, if we wanted to fix the, not the error,

177
00:09:45.520 --> 00:09:49.283
but the fact that the three is printed before the two,

178
00:09:50.260 --> 00:09:52.063
well then how would we do that?

179
00:09:53.100 --> 00:09:57.500
Well, we can simply add a finally here, right?

180
00:09:57.500 --> 00:09:59.970
Because the finally, as you already know,

181
00:09:59.970 --> 00:10:03.250
is always gonna be executed.

182
00:10:03.250 --> 00:10:04.443
So no matter what,

183
00:10:08.550 --> 00:10:09.383
all right?

184
00:10:10.720 --> 00:10:12.490
So now we only get the one

185
00:10:12.490 --> 00:10:14.960
then we should get the two with the error

186
00:10:14.960 --> 00:10:16.260
and then the number three.

187
00:10:18.540 --> 00:10:22.083
And indeed, if we remove now the error from here,

188
00:10:24.120 --> 00:10:27.783
then one, two, three, just as expected,

189
00:10:29.776 --> 00:10:31.130
all right?

190
00:10:31.130 --> 00:10:35.230
So I admit that this might've been a little bit confusing,

191
00:10:35.230 --> 00:10:37.030
but I hope that you understood

192
00:10:37.030 --> 00:10:40.350
how all the pieces fit together here.

193
00:10:40.350 --> 00:10:44.010
Now this of course works just fine, but in my opinion,

194
00:10:44.010 --> 00:10:46.090
there's still a problem here.

195
00:10:46.090 --> 00:10:49.600
And that problem is the fact that doing this here

196
00:10:50.600 --> 00:10:53.820
kind of makes this the philosophy of async/await

197
00:10:53.820 --> 00:10:58.820
with handling promises using then and catch, right?

198
00:10:59.320 --> 00:11:00.850
So we are mixing the old

199
00:11:00.850 --> 00:11:03.840
and the new way of working with promises here,

200
00:11:03.840 --> 00:11:05.400
all in the same code.

201
00:11:05.400 --> 00:11:08.840
And that's something that I personally don't like.

202
00:11:08.840 --> 00:11:11.970
So I prefer to always just use async functions

203
00:11:11.970 --> 00:11:13.683
instead of having to mix them.

204
00:11:14.720 --> 00:11:15.960
And so let's now go ahead

205
00:11:15.960 --> 00:11:19.560
and convert this to async/await as well.

206
00:11:19.560 --> 00:11:21.920
And we can do that because, of course,

207
00:11:21.920 --> 00:11:25.520
we can treat the promise here that has returned

208
00:11:25.520 --> 00:11:27.750
just like any other promise.

209
00:11:27.750 --> 00:11:30.370
And so of course we are able to handle it

210
00:11:30.370 --> 00:11:32.260
using async/await.

211
00:11:32.260 --> 00:11:34.840
So that's what we're going to do next.

212
00:11:34.840 --> 00:11:38.190
Now it would be great if we could simply use await

213
00:11:38.190 --> 00:11:40.590
without the async function,

214
00:11:40.590 --> 00:11:44.510
but that doesn't really work, at least for now,

215
00:11:44.510 --> 00:11:47.610
because there is actually a proposal in the works

216
00:11:47.610 --> 00:11:50.220
to make this happen, but for now,

217
00:11:50.220 --> 00:11:54.270
await can only be used inside an async function.

218
00:11:54.270 --> 00:11:58.860
However, we don't really want a new complete function here,

219
00:11:58.860 --> 00:12:01.950
and so instead we can use an IIFE.

220
00:12:01.950 --> 00:12:04.950
So remember IIFEs from way back,

221
00:12:04.950 --> 00:12:08.060
they are immediately-invoked function expressions.

222
00:12:08.060 --> 00:12:11.393
And remember that this is how we create one.

223
00:12:12.860 --> 00:12:14.780
So we write function

224
00:12:15.980 --> 00:12:18.330
then here the function body,

225
00:12:18.330 --> 00:12:21.200
and then in the end we simply call it.

226
00:12:21.200 --> 00:12:24.750
And so of course we can also easily create

227
00:12:24.750 --> 00:12:25.583
an async

228
00:12:27.038 --> 00:12:28.410
IIFE as well,

229
00:12:28.410 --> 00:12:29.460
all right?

230
00:12:29.460 --> 00:12:31.990
And actually this pattern here

231
00:12:31.990 --> 00:12:36.990
is one of the last remaining cases for IIFEs, all right?

232
00:12:37.010 --> 00:12:40.880
And now I actually want to leave the conversion of this

233
00:12:40.880 --> 00:12:44.650
to the async function for you as a small challenge.

234
00:12:44.650 --> 00:12:46.610
So please pause the video now

235
00:12:46.610 --> 00:12:48.430
and take a minute or two

236
00:12:48.430 --> 00:12:50.393
and write the code yourself here.

237
00:12:51.870 --> 00:12:53.390
All right.

238
00:12:53.390 --> 00:12:56.823
So let's start with the try catch block.

239
00:12:58.720 --> 00:13:02.940
So try catch, here We get access to the error

240
00:13:04.470 --> 00:13:08.233
and then let's actually immediately do this part.

241
00:13:11.010 --> 00:13:16.010
And then here we can simply await the whereAmI promise,

242
00:13:18.030 --> 00:13:18.890
okay?

243
00:13:18.890 --> 00:13:23.020
And then all we have to do is to store that result

244
00:13:23.020 --> 00:13:27.453
into the city variable and then log that to the console.

245
00:13:29.030 --> 00:13:30.963
So that's just this,

246
00:13:32.500 --> 00:13:35.090
and now finally, this last part here,

247
00:13:35.090 --> 00:13:39.120
we can simply put it outside of the try catch block.

248
00:13:39.120 --> 00:13:42.893
And so then it is always gonna be executed no matter what.

249
00:13:44.640 --> 00:13:45.970
Okay?

250
00:13:45.970 --> 00:13:47.550
So let's comment this one out

251
00:13:48.760 --> 00:13:51.950
and we should get the exact same result

252
00:13:51.950 --> 00:13:53.530
and let's wait for it.

253
00:13:53.530 --> 00:13:55.080
And here we go.

254
00:13:55.080 --> 00:13:58.450
So great. We managed to do the conversion

255
00:13:58.450 --> 00:14:02.470
and now everything is using async/await.

256
00:14:02.470 --> 00:14:04.570
And so that's much nicer.

257
00:14:04.570 --> 00:14:08.590
And now we know how to basically return data

258
00:14:08.590 --> 00:14:10.540
from an async function

259
00:14:10.540 --> 00:14:14.920
and how to properly receive and handle that returned data.

260
00:14:14.920 --> 00:14:16.160
Right?

261
00:14:16.160 --> 00:14:18.030
And actually in the real life,

262
00:14:18.030 --> 00:14:21.150
this is something that happens all the time.

263
00:14:21.150 --> 00:14:23.870
So it's pretty common that we have async functions

264
00:14:23.870 --> 00:14:26.190
calling other async functions

265
00:14:26.190 --> 00:14:28.740
and returning values between them.

266
00:14:28.740 --> 00:14:31.590
And so that's the reason why I'm showing you all this.

267
00:14:31.590 --> 00:14:34.550
To make sure that you really correctly understand

268
00:14:34.550 --> 00:14:37.433
how async functions work behind the scenes.

