WEBVTT

1
00:00:01.230 --> 00:00:02.460
<v Jonas>In the last video,</v>

2
00:00:02.460 --> 00:00:07.460
we got a glimpse into Callback Hell, and it was not pretty.

3
00:00:07.590 --> 00:00:09.000
So in this lecture,

4
00:00:09.000 --> 00:00:11.760
let's learn about a modern JavaScript feature

5
00:00:11.760 --> 00:00:13.260
called Promises,

6
00:00:13.260 --> 00:00:15.903
so that we can escape Callback Hell.

7
00:00:17.310 --> 00:00:20.220
However, before we learn about promises,

8
00:00:20.220 --> 00:00:22.710
we should actually see one.

9
00:00:22.710 --> 00:00:27.660
And so let's now replace the old XML HTTP request function

10
00:00:27.660 --> 00:00:31.170
with the modern way of making AJAX calls,

11
00:00:31.170 --> 00:00:33.903
and that is by using the Fetch API.

12
00:00:35.340 --> 00:00:39.243
So let me go up here to our first function,

13
00:00:40.860 --> 00:00:43.270
and I will just copy all of this

14
00:00:44.880 --> 00:00:48.573
just to see how it used to work and how we can do it now.

15
00:00:51.690 --> 00:00:52.523
Okay.

16
00:00:53.520 --> 00:00:57.570
So, this is how we used to do it,

17
00:00:57.570 --> 00:01:01.083
and now all we need to do is to call Fetch,

18
00:01:02.160 --> 00:01:04.263
and then with our URL,

19
00:01:05.940 --> 00:01:10.940
so let's just grab that part and then specify Portugal,

20
00:01:11.970 --> 00:01:13.830
and that's actually it.

21
00:01:13.830 --> 00:01:14.850
All we have to do now

22
00:01:14.850 --> 00:01:18.540
is to store the result into a variable,

23
00:01:18.540 --> 00:01:22.350
and let's still call it "request" here.

24
00:01:22.350 --> 00:01:24.840
Now, there are actually some more options

25
00:01:24.840 --> 00:01:29.040
that we can specify here in the Fetch function if we'd like,

26
00:01:29.040 --> 00:01:32.400
but to make a simple get request like this one,

27
00:01:32.400 --> 00:01:37.290
all we really need is to pass in the URL and that's it.

28
00:01:37.290 --> 00:01:39.810
So for more complex AJAX calls,

29
00:01:39.810 --> 00:01:42.060
the Fetch function can take in

30
00:01:42.060 --> 00:01:44.790
like an object of options as well.

31
00:01:44.790 --> 00:01:47.433
But again, for now, we don't need that.

32
00:01:48.360 --> 00:01:50.253
But anyway, let's now give it a safe,

33
00:01:51.150 --> 00:01:55.380
and well, we should also log the request to the console

34
00:01:55.380 --> 00:01:56.613
to see what happens.

35
00:01:57.450 --> 00:01:59.760
And so you see that the Fetch function

36
00:01:59.760 --> 00:02:02.790
immediately returned a promise here.

37
00:02:02.790 --> 00:02:05.250
So as soon as we started the request,

38
00:02:05.250 --> 00:02:09.660
we stored the result of that into the request variable.

39
00:02:09.660 --> 00:02:11.400
And then as we logged it,

40
00:02:11.400 --> 00:02:13.773
we immediately got the promise here.

41
00:02:14.670 --> 00:02:16.710
So let's do that again.

42
00:02:16.710 --> 00:02:20.670
And again, right away, we got something called promise.

43
00:02:20.670 --> 00:02:22.347
And here, it says "pending."

44
00:02:23.280 --> 00:02:26.907
So if we open that up, then here it says "fulfilled."

45
00:02:27.780 --> 00:02:30.480
Then we also have like a value here,

46
00:02:30.480 --> 00:02:33.453
but I'm not gonna go into full detail just yet.

47
00:02:34.440 --> 00:02:36.600
So what matters here is that now,

48
00:02:36.600 --> 00:02:38.670
we actually have a promise,

49
00:02:38.670 --> 00:02:41.190
and so this promise is right now stored

50
00:02:41.190 --> 00:02:43.740
in this request variable.

51
00:02:43.740 --> 00:02:46.710
But now, what exactly is a promise,

52
00:02:46.710 --> 00:02:48.870
and what can we do with it?

53
00:02:48.870 --> 00:02:50.583
Well, let's find out.

54
00:02:51.840 --> 00:02:54.600
So, the formal definition of a promise

55
00:02:54.600 --> 00:02:56.250
is that it's an object

56
00:02:56.250 --> 00:02:59.070
that is used basically as a placeholder

57
00:02:59.070 --> 00:03:03.090
for the future result of an asynchronous operation.

58
00:03:03.090 --> 00:03:05.550
And if that sounds weird to you,

59
00:03:05.550 --> 00:03:09.300
we can also say that a promise is like a container

60
00:03:09.300 --> 00:03:12.600
for an asynchronously delivered value.

61
00:03:12.600 --> 00:03:14.430
Or even less formal,

62
00:03:14.430 --> 00:03:19.260
let's say that a promise is a container for a future value.

63
00:03:19.260 --> 00:03:21.030
So there you go.

64
00:03:21.030 --> 00:03:23.760
That's the most distilled down definition

65
00:03:23.760 --> 00:03:25.710
of what a promise is.

66
00:03:25.710 --> 00:03:30.390
So a container or a placeholder for a future value.

67
00:03:30.390 --> 00:03:33.480
And the perfect example of a future value

68
00:03:33.480 --> 00:03:37.380
is the response coming from an AJAX call.

69
00:03:37.380 --> 00:03:41.910
So when we start the AJAX call, there is no value yet,

70
00:03:41.910 --> 00:03:45.600
but we know that there will be some value in the future,

71
00:03:45.600 --> 00:03:50.040
and so we can use a promise to handle this future value.

72
00:03:50.040 --> 00:03:51.210
And don't worry,

73
00:03:51.210 --> 00:03:55.530
this will really make sense once we go back to code.

74
00:03:55.530 --> 00:03:58.290
But to understand this concept even better,

75
00:03:58.290 --> 00:04:02.580
I like to use the analogy of a lottery ticket.

76
00:04:02.580 --> 00:04:06.570
So a promise is just like a lottery ticket.

77
00:04:06.570 --> 00:04:09.120
So when I buy a lottery ticket,

78
00:04:09.120 --> 00:04:11.340
essentially, I buy the promise

79
00:04:11.340 --> 00:04:14.820
that I will receive some amount of money in the future

80
00:04:14.820 --> 00:04:18.420
if I guess the correct outcome, right?

81
00:04:18.420 --> 00:04:20.610
So I buy the ticket now

82
00:04:20.610 --> 00:04:23.820
with the prospect of winning money in the future,

83
00:04:23.820 --> 00:04:25.140
and the lottery draw,

84
00:04:25.140 --> 00:04:27.720
which determines if I get the money or not,

85
00:04:27.720 --> 00:04:30.090
happens asynchronously.

86
00:04:30.090 --> 00:04:33.270
So of course I don't have to drop everything

87
00:04:33.270 --> 00:04:37.053
and keep waiting until the lottery draw happens, right?

88
00:04:37.950 --> 00:04:40.950
Now, in case I did get the correct outcome,

89
00:04:40.950 --> 00:04:42.960
then I will receive my money

90
00:04:42.960 --> 00:04:45.210
because I have my lottery ticket,

91
00:04:45.210 --> 00:04:48.090
which is the promise that I bought.

92
00:04:48.090 --> 00:04:52.260
Now, what's the big advantage of using promises?

93
00:04:52.260 --> 00:04:55.290
Well, there are two of them actually.

94
00:04:55.290 --> 00:04:57.360
First, by using promises,

95
00:04:57.360 --> 00:05:01.680
we no longer need to rely on events and callback functions

96
00:05:01.680 --> 00:05:04.350
to handle asynchronous results.

97
00:05:04.350 --> 00:05:06.180
Events and callback functions

98
00:05:06.180 --> 00:05:09.270
can sometimes cause unpredictable results.

99
00:05:09.270 --> 00:05:12.150
And so this is a big win already.

100
00:05:12.150 --> 00:05:16.080
But even better, with promises, we can chain promises

101
00:05:16.080 --> 00:05:19.230
for a sequence of asynchronous operations

102
00:05:19.230 --> 00:05:23.610
instead of nesting like we did in the last video.

103
00:05:23.610 --> 00:05:26.760
And with this, we can finally escape Callback Hell,

104
00:05:26.760 --> 00:05:29.910
which was our initial goal all along.

105
00:05:29.910 --> 00:05:33.540
And by the way, promises are an ES6 feature,

106
00:05:33.540 --> 00:05:37.860
so they became available in JavaScript in 2015.

107
00:05:37.860 --> 00:05:41.433
And so by now, they are widely used by everyone.

108
00:05:43.170 --> 00:05:47.430
Now, since promises work with asynchronous operations,

109
00:05:47.430 --> 00:05:49.380
they are time sensitive,

110
00:05:49.380 --> 00:05:51.510
so they change over time,

111
00:05:51.510 --> 00:05:55.290
and so promises can be in different states,

112
00:05:55.290 --> 00:05:59.400
and this is what we call the life cycle of a promise.

113
00:05:59.400 --> 00:06:01.020
So in the very beginning,

114
00:06:01.020 --> 00:06:04.140
we say that the promise is pending,

115
00:06:04.140 --> 00:06:06.060
and so this is before any value

116
00:06:06.060 --> 00:06:10.440
resulting from the asynchronous task is available.

117
00:06:10.440 --> 00:06:12.060
Now, during this time,

118
00:06:12.060 --> 00:06:15.420
the asynchronous task is still doing its work

119
00:06:15.420 --> 00:06:16.473
in the background.

120
00:06:17.310 --> 00:06:20.190
Then when the task finally finishes,

121
00:06:20.190 --> 00:06:22.473
we say that the promise is settled.

122
00:06:23.310 --> 00:06:27.150
And there are two different types of settled promises,

123
00:06:27.150 --> 00:06:31.800
and that's fulfilled promises and rejected promises.

124
00:06:31.800 --> 00:06:33.780
So a fulfilled promise,

125
00:06:33.780 --> 00:06:36.750
is a promise that has successfully resulted

126
00:06:36.750 --> 00:06:39.570
in a value just as we expected.

127
00:06:39.570 --> 00:06:41.700
For example, when we use a promise

128
00:06:41.700 --> 00:06:44.220
to fetch data from an API,

129
00:06:44.220 --> 00:06:47.730
a fulfilled promise successfully got that data,

130
00:06:47.730 --> 00:06:50.910
and it's now available to being used.

131
00:06:50.910 --> 00:06:52.020
On the other hand,

132
00:06:52.020 --> 00:06:55.650
a rejected promise means that there has been an error

133
00:06:55.650 --> 00:06:58.170
during the asynchronous task.

134
00:06:58.170 --> 00:07:01.560
In the example of fetching data from an API,

135
00:07:01.560 --> 00:07:05.280
an error would be, for example, when the user is offline

136
00:07:05.280 --> 00:07:07.773
and can connect to the API server.

137
00:07:08.760 --> 00:07:12.270
Now, going back to the analogy of our lottery ticket,

138
00:07:12.270 --> 00:07:15.930
the lottery draw is basically the asynchronous task,

139
00:07:15.930 --> 00:07:18.300
which determines the result.

140
00:07:18.300 --> 00:07:20.730
Then once the result is available,

141
00:07:20.730 --> 00:07:23.190
the ticket would be settled.

142
00:07:23.190 --> 00:07:26.070
Then if we guessed the correct outcome,

143
00:07:26.070 --> 00:07:30.360
the lottery ticket would be fulfilled and we get our money.

144
00:07:30.360 --> 00:07:32.520
However, if we guessed wrong,

145
00:07:32.520 --> 00:07:35.100
then the ticket basically gets rejected,

146
00:07:35.100 --> 00:07:38.163
and all we did was waste our money.

147
00:07:39.120 --> 00:07:42.930
Now, these different states are very important to understand

148
00:07:42.930 --> 00:07:45.990
because when we use promises in our code,

149
00:07:45.990 --> 00:07:49.050
we will be able to handle these different states

150
00:07:49.050 --> 00:07:51.600
in order to do something as a result

151
00:07:51.600 --> 00:07:55.560
of either a successful promise or a rejected one.

152
00:07:55.560 --> 00:07:58.020
Another important thing about promises,

153
00:07:58.020 --> 00:08:01.020
is that a promise is only settled once,

154
00:08:01.020 --> 00:08:04.803
and so from there, the state will remain unchanged forever.

155
00:08:05.700 --> 00:08:09.300
So the promise was either fulfilled or rejected,

156
00:08:09.300 --> 00:08:11.973
but it's impossible to change that state.

157
00:08:12.810 --> 00:08:15.990
Now, these different states that I showed you here

158
00:08:15.990 --> 00:08:17.700
are relevant and useful

159
00:08:17.700 --> 00:08:20.520
when we use a promise to get a result,

160
00:08:20.520 --> 00:08:24.030
which is called to consume a promise.

161
00:08:24.030 --> 00:08:28.020
So we consume a promise when we already have a promise.

162
00:08:28.020 --> 00:08:30.630
For example, the promise that was returned

163
00:08:30.630 --> 00:08:31.950
from the fetch function

164
00:08:31.950 --> 00:08:35.340
right at the beginning of this video, remember?

165
00:08:35.340 --> 00:08:38.970
But in order for a promise to exist in the first place,

166
00:08:38.970 --> 00:08:40.860
it must first be built.

167
00:08:40.860 --> 00:08:43.020
So it must be created.

168
00:08:43.020 --> 00:08:45.510
In the case of the fetch API,

169
00:08:45.510 --> 00:08:48.330
it's the Fetch function that builds the promise

170
00:08:48.330 --> 00:08:51.000
and returns it for us to consume.

171
00:08:51.000 --> 00:08:51.870
So in this case,

172
00:08:51.870 --> 00:08:54.300
we don't have to build the promise ourselves

173
00:08:54.300 --> 00:08:56.160
in order to consume it.

174
00:08:56.160 --> 00:08:57.600
Now, most of the time,

175
00:08:57.600 --> 00:09:00.240
we will actually just consume promises,

176
00:09:00.240 --> 00:09:03.810
which is also the easier and more useful part.

177
00:09:03.810 --> 00:09:07.620
And so that's what we will do in the next couple of videos.

178
00:09:07.620 --> 00:09:10.500
But sometimes we also need to build a promise

179
00:09:10.500 --> 00:09:12.300
and not just consume it.

180
00:09:12.300 --> 00:09:14.010
And of course, we will also learn

181
00:09:14.010 --> 00:09:16.143
how to do that a bit later.

182
00:09:17.250 --> 00:09:18.990
All right, and so now,

183
00:09:18.990 --> 00:09:22.563
let's actually start using promises in the next video.

