1
00:00:00,924 --> 00:00:03,430
<v Jonas>Let's now quickly talk about</v>

2
00:00:03,430 --> 00:00:05,970
the three other Promise combinators,

3
00:00:05,970 --> 00:00:09,383
which are race, allSettled and any.

4
00:00:10,960 --> 00:00:15,653
And the first one we're gonna talk about is Promise.race.

5
00:00:16,860 --> 00:00:18,610
So like this .

6
00:00:18,610 --> 00:00:21,939
And Promise.race, just like all other combinators,

7
00:00:21,939 --> 00:00:26,939
receives an array of promises and it also returns a promise.

8
00:00:27,420 --> 00:00:30,698
Now this promise returned by Promise.race

9
00:00:30,698 --> 00:00:35,698
is settled as soon as one of the input promises settles.

10
00:00:36,060 --> 00:00:38,680
And remember that settled simply means

11
00:00:38,680 --> 00:00:40,720
that a value is available,

12
00:00:40,720 --> 00:00:41,880
but it doesn't matter

13
00:00:41,880 --> 00:00:44,982
if the promise got rejected or fulfilled.

14
00:00:44,982 --> 00:00:47,390
And so in Promis.race,

15
00:00:47,390 --> 00:00:51,420
basically the first settled promise wins the race.

16
00:00:51,420 --> 00:00:54,208
But let's now actually see this in action.

17
00:00:54,208 --> 00:00:56,880
And I will create a quick IIFE here

18
00:00:56,880 --> 00:00:59,720
so that I can use async await

19
00:00:59,720 --> 00:01:04,003
without like creating a whole new function with a name.

20
00:01:08,580 --> 00:01:13,580
And so as always then we use await Promise

21
00:01:14,020 --> 00:01:15,170
and in this case .race,

22
00:01:16,810 --> 00:01:21,810
and let's also now store it here as a response.

23
00:01:23,400 --> 00:01:26,880
And now here let's define an array of promises

24
00:01:27,753 --> 00:01:32,510
and lets just get this JSON here,

25
00:01:32,510 --> 00:01:37,510
let's getJSON function and try it with three countries.

26
00:01:38,910 --> 00:01:40,243
Let's say Italy,

27
00:01:43,140 --> 00:01:45,165
and do this three times.

28
00:01:45,165 --> 00:01:49,557
Let's say Egypt and then also Mexico.

29
00:01:51,520 --> 00:01:54,260
And so now these three promises will basically

30
00:01:54,260 --> 00:01:57,980
race against each other, like in a real race.

31
00:01:57,980 --> 00:02:01,680
Now, if the winning promise is then a fulfilled promise,

32
00:02:01,680 --> 00:02:06,160
then the fulfillment value of this whole race promise

33
00:02:06,160 --> 00:02:09,743
is gonna be the fulfillment value of the winning promise.

34
00:02:11,610 --> 00:02:14,900
So that's more obvious than it maybe sound.

35
00:02:14,900 --> 00:02:18,454
So let's just see the result here in the console.

36
00:02:18,454 --> 00:02:22,890
And so we got Italy, but if we try it again,

37
00:02:22,890 --> 00:02:25,130
then maybe we get another result

38
00:02:25,130 --> 00:02:28,253
because then maybe another call is gonna be faster.

39
00:02:29,230 --> 00:02:34,210
But well, it seems to be always Italy but now it's Mexico

40
00:02:34,210 --> 00:02:36,603
and let's actually see this in the network tab.

41
00:02:38,350 --> 00:02:40,680
So making it smaller again.

42
00:02:40,680 --> 00:02:43,020
And so you see that indeed Mexico

43
00:02:43,020 --> 00:02:45,630
is the one who took the least time.

44
00:02:45,630 --> 00:02:47,800
So test the smallest bar here.

45
00:02:47,800 --> 00:02:52,800
And it also was the fastest of the three, right?

46
00:02:53,320 --> 00:02:56,890
This time, the fastest was Egypt here by far.

47
00:02:56,890 --> 00:02:59,290
And so that's what we should see in the console.

48
00:03:00,840 --> 00:03:03,670
Okay, so again, just keep in mind

49
00:03:03,670 --> 00:03:05,730
that here in Promised.race,

50
00:03:05,730 --> 00:03:07,490
we only get one result

51
00:03:07,490 --> 00:03:11,053
and not an array of the results of all the three.

52
00:03:11,980 --> 00:03:14,070
Now a promise that gets rejected

53
00:03:14,070 --> 00:03:16,550
can actually also win the race.

54
00:03:16,550 --> 00:03:19,444
And so we say that Promise.race short circuits

55
00:03:19,444 --> 00:03:22,920
whenever one of the promises gets settled.

56
00:03:22,920 --> 00:03:27,123
And so again, that means no matter if fulfilled or rejected.

57
00:03:28,240 --> 00:03:30,173
So let's try some weird name here.

58
00:03:32,480 --> 00:03:36,883
And so now it is the rejected promise that won basically.

59
00:03:38,530 --> 00:03:41,423
But let's go back here to as it was,

60
00:03:42,770 --> 00:03:45,940
and see another example because in the real world

61
00:03:45,940 --> 00:03:48,810
Promise.race is actually very useful

62
00:03:48,810 --> 00:03:51,930
to prevent against never ending promises

63
00:03:51,930 --> 00:03:55,110
or also very long running promises.

64
00:03:55,110 --> 00:03:56,880
For example, if your user

65
00:03:56,880 --> 00:03:59,430
has a very bad internet connection,

66
00:03:59,430 --> 00:04:01,940
then a fetch requests in your application

67
00:04:01,940 --> 00:04:05,580
might take way too long to actually be useful.

68
00:04:05,580 --> 00:04:08,790
And so we can create a special time out promise,

69
00:04:08,790 --> 00:04:13,370
which automatically rejects after a certain time has passed.

70
00:04:13,370 --> 00:04:15,060
So let's do that.

71
00:04:15,060 --> 00:04:17,820
And it's gonna be similar to the wait function

72
00:04:17,820 --> 00:04:19,270
that we created earlier.

73
00:04:19,270 --> 00:04:22,930
But the difference is that this one is actually going

74
00:04:22,930 --> 00:04:25,763
to reject and not going to resolve.

75
00:04:27,130 --> 00:04:31,820
So this time let's actually pass in milliseconds, right?

76
00:04:31,820 --> 00:04:34,690
Well, let's just pass in seconds

77
00:04:34,690 --> 00:04:37,003
just to make it consistent with the other one.

78
00:04:38,020 --> 00:04:40,220
So return new Promise

79
00:04:43,280 --> 00:04:45,310
and execute a function.

80
00:04:45,310 --> 00:04:49,034
And again, in this case, we will not resolve but reject.

81
00:04:49,034 --> 00:04:51,180
And so here for the resolve function,

82
00:04:51,180 --> 00:04:54,430
which is always the first one we can once again,

83
00:04:54,430 --> 00:04:57,090
use this throw away variable.

84
00:04:57,090 --> 00:04:58,520
So using this convention

85
00:05:00,670 --> 00:05:03,970
and then here reject and setTimeout

86
00:05:05,962 --> 00:05:08,973
and here we specify a callback function.

87
00:05:10,410 --> 00:05:14,660
And so we say that after a certain amount of seconds,

88
00:05:14,660 --> 00:05:18,413
let's call it sec like this actually.

89
00:05:20,220 --> 00:05:23,743
So after this time has passed, we reject the promise.

90
00:05:25,000 --> 00:05:26,460
So we create a new error

91
00:05:28,640 --> 00:05:32,507
saying, "Requests took too long."

92
00:05:34,357 --> 00:05:37,740
And so now we can simply have the Ajax call

93
00:05:37,740 --> 00:05:40,230
that we were talking about earlier,

94
00:05:40,230 --> 00:05:43,210
raced against this timeout.

95
00:05:43,210 --> 00:05:46,673
All right, so let me show you what that means.

96
00:05:49,930 --> 00:05:51,943
So Promise.race,

97
00:05:53,880 --> 00:05:57,330
and then here, the first promise,

98
00:05:57,330 --> 00:05:59,173
let's use again or getJSON.

99
00:06:00,870 --> 00:06:04,690
So this is basically what we are interested in here

100
00:06:04,690 --> 00:06:09,150
and let's use another country Tanzania again.

101
00:06:09,150 --> 00:06:12,533
And the second promise is then going to be or timeout.

102
00:06:14,720 --> 00:06:18,343
So let's say that we only want to wait like one second.

103
00:06:19,780 --> 00:06:24,190
And so we will have these two then race against each other.

104
00:06:24,190 --> 00:06:26,410
And if the timeout happens first,

105
00:06:26,410 --> 00:06:30,170
then all of this here will be rejected, right?

106
00:06:30,170 --> 00:06:33,470
And so basically that will then abort the fetch

107
00:06:33,470 --> 00:06:36,170
that is happening here in getJSON.

108
00:06:36,170 --> 00:06:39,303
So I could have used again async await,

109
00:06:40,920 --> 00:06:43,663
but why not use the then method also here?

110
00:06:47,670 --> 00:06:52,670
So in this case, let's just log the response

111
00:06:52,946 --> 00:06:54,743
or we could have called it data,

112
00:06:55,890 --> 00:06:58,600
but that's not really important here

113
00:06:59,831 --> 00:07:01,223
and here the error,

114
00:07:02,530 --> 00:07:06,313
and lets just also log to the console in case there is any.

115
00:07:09,330 --> 00:07:12,760
And so now we have "Request took too long."

116
00:07:12,760 --> 00:07:15,580
But that was very fast.

117
00:07:15,580 --> 00:07:19,420
I went here, we have to multiply it by a 1000.

118
00:07:19,420 --> 00:07:23,293
So again, this one takes milliseconds and not just seconds.

119
00:07:25,330 --> 00:07:28,410
Okay, so we got to Tanzania pretty fast.

120
00:07:28,410 --> 00:07:30,820
And so it was faster than one second.

121
00:07:30,820 --> 00:07:35,000
And so therefore it did not timeout.

122
00:07:35,000 --> 00:07:37,403
But let's now try 0.1 seconds.

123
00:07:38,400 --> 00:07:41,980
And so now we see that the request took too long.

124
00:07:41,980 --> 00:07:44,870
So 0.1 seconds was not enough

125
00:07:44,870 --> 00:07:48,020
for this request here to get finished.

126
00:07:48,020 --> 00:07:50,934
And you will have to experiment with different values here

127
00:07:50,934 --> 00:07:55,820
because this is going to depend on your internet connection.

128
00:07:55,820 --> 00:07:58,086
So let's see 0.2 seconds.

129
00:07:58,086 --> 00:08:02,240
And so now the request was actually fast enough

130
00:08:02,240 --> 00:08:04,700
so that it didn't timeout.

131
00:08:04,700 --> 00:08:09,700
So with 0.15 seconds, again it takes too long.

132
00:08:10,430 --> 00:08:15,430
And so then this promise here is the result of Promise.race.

133
00:08:16,690 --> 00:08:18,068
So that's pretty useful.

134
00:08:18,068 --> 00:08:19,380
And in the real world

135
00:08:19,380 --> 00:08:22,590
of course you will use a larger number.

136
00:08:22,590 --> 00:08:25,023
Let's say like five seconds.

137
00:08:26,020 --> 00:08:29,510
Now, okay, so that's Promis.race

138
00:08:29,510 --> 00:08:33,100
and in fact Promise.race and Promise.all

139
00:08:33,100 --> 00:08:37,360
are by far the two most important promise combinators.

140
00:08:37,360 --> 00:08:40,283
But let me show you also the other two that we have.

141
00:08:41,460 --> 00:08:42,370
So the next one

142
00:08:43,430 --> 00:08:45,340
is Promise.allSettled.

143
00:08:48,561 --> 00:08:50,610
And this one is a pretty new one.

144
00:08:50,610 --> 00:08:55,560
It is from ES2020 and it is actually a very simple one.

145
00:08:55,560 --> 00:08:58,480
So it takes in an array of promises again,

146
00:08:58,480 --> 00:09:00,510
and it will simply return an array

147
00:09:00,510 --> 00:09:02,810
of all the settled promises.

148
00:09:02,810 --> 00:09:07,810
And so again, no matter if the promises got rejected or not.

149
00:09:08,430 --> 00:09:10,278
So it's similar to Promise.all

150
00:09:10,278 --> 00:09:15,180
in regard that it also returns an array of all the results,

151
00:09:15,180 --> 00:09:17,720
but the difference is that Promise.all

152
00:09:17,720 --> 00:09:21,770
will short circuit as soon as one promise rejects,

153
00:09:21,770 --> 00:09:26,380
but Promise.allSettled, simply never short circuits.

154
00:09:26,380 --> 00:09:27,720
So it will simply return

155
00:09:27,720 --> 00:09:30,193
all the results of all the promises.

156
00:09:31,220 --> 00:09:33,260
So Promise.allSettled.

157
00:09:38,347 --> 00:09:40,550
And so now here I will create

158
00:09:40,550 --> 00:09:44,290
actually the most basic example ever.

159
00:09:44,290 --> 00:09:47,330
So I will simply fake promises

160
00:09:47,330 --> 00:09:50,120
by saying Promise.resolve

161
00:09:51,440 --> 00:09:54,170
Success, all right.

162
00:09:54,170 --> 00:09:57,490
And so you already know that this here automatically creates

163
00:09:57,490 --> 00:10:00,180
a promise that is resolved.

164
00:10:00,180 --> 00:10:03,120
And so we don't have to wait for anything to finish

165
00:10:03,120 --> 00:10:05,613
like this here, okay?

166
00:10:07,200 --> 00:10:09,950
So then we can have a couple of more.

167
00:10:09,950 --> 00:10:11,693
Here we have a rejected one.

168
00:10:14,530 --> 00:10:16,993
So let's say ERROR and here another one,

169
00:10:18,200 --> 00:10:21,173
let's say Another success.

170
00:10:22,160 --> 00:10:26,090
Now, okay, and then here we can just call then

171
00:10:27,390 --> 00:10:28,253
and let's see.

172
00:10:30,120 --> 00:10:34,173
Now here we want actually all of the results.

173
00:10:36,630 --> 00:10:40,140
And so indeed here we get three results,

174
00:10:40,140 --> 00:10:44,780
even though one of them rejected, okay?

175
00:10:44,780 --> 00:10:47,420
So this is the result of the three promises

176
00:10:48,815 --> 00:10:52,030
and yeah, so this is how they look like

177
00:10:52,030 --> 00:10:56,310
when we do them manually with resolve, reject and resolve.

178
00:10:56,310 --> 00:11:00,963
Just contrast that with Promise.all,

179
00:11:03,120 --> 00:11:05,730
so that would then look different.

180
00:11:05,730 --> 00:11:09,750
So here we would get an error, okay.

181
00:11:09,750 --> 00:11:12,223
So of course we can also catch the error then.

182
00:11:14,540 --> 00:11:18,345
And so here we will simply get error and that's again...

183
00:11:18,345 --> 00:11:22,970
Because the .allpromise combinator will short circuit

184
00:11:22,970 --> 00:11:27,133
if there is one error, if there is one rejected promise.

185
00:11:28,230 --> 00:11:30,380
So that's the difference between these two.

186
00:11:32,620 --> 00:11:35,070
But now let's go to the last one,

187
00:11:35,070 --> 00:11:39,063
which is Promise.any.

188
00:11:40,580 --> 00:11:41,633
So like this.

189
00:11:43,180 --> 00:11:46,110
Now Promise.any is even more modern.

190
00:11:46,110 --> 00:11:50,950
It is ES2021 and actually at the time of recording,

191
00:11:50,950 --> 00:11:53,460
this one doesn't work in my browser,

192
00:11:53,460 --> 00:11:56,190
but probably by the time I'm releasing this course,

193
00:11:56,190 --> 00:11:59,360
it will work in the latest version of Google Chrome.

194
00:11:59,360 --> 00:12:02,603
And so let me simply do this here as well.

195
00:12:03,570 --> 00:12:07,523
So all am gonna do is to just copy this example here

196
00:12:07,523 --> 00:12:12,340
and then do any, and this is not going to work.

197
00:12:12,340 --> 00:12:14,000
Let me show you.

198
00:12:14,000 --> 00:12:17,120
So we get Promised.any is not a function.

199
00:12:17,120 --> 00:12:21,110
But again in your case, it might already work.

200
00:12:21,110 --> 00:12:24,740
So let me simply explain what it does.

201
00:12:24,740 --> 00:12:28,220
So as always Promise.any takes in an array

202
00:12:28,220 --> 00:12:31,970
of multiple promises and this one will then return

203
00:12:31,970 --> 00:12:34,210
the first fulfilled promise

204
00:12:34,210 --> 00:12:37,730
and it will simply ignore rejected promises.

205
00:12:37,730 --> 00:12:40,620
So basically Promise.any is very similar

206
00:12:40,620 --> 00:12:43,440
to Promise.race with the difference

207
00:12:43,440 --> 00:12:46,480
that rejected promises are ignored.

208
00:12:46,480 --> 00:12:50,000
And so therefore the results of Promise.any

209
00:12:50,000 --> 00:12:52,890
is always gonna be a fulfilled promise,

210
00:12:52,890 --> 00:12:56,490
unless of course all of them reject, okay.

211
00:12:56,490 --> 00:12:58,810
But at the time you're watching this video

212
00:12:58,810 --> 00:13:01,140
again, this should already work.

213
00:13:01,140 --> 00:13:04,060
And then maybe you can experiment a little bit with this

214
00:13:04,060 --> 00:13:05,640
to see the difference between

215
00:13:05,640 --> 00:13:08,260
all the four Promise combinators.

216
00:13:08,260 --> 00:13:09,960
And again, the most important ones

217
00:13:09,960 --> 00:13:14,050
are definitely Promise.all and Promise.race.

218
00:13:14,050 --> 00:13:17,603
So keep at least these two in mind for your own projects.

