1
00:00:02,330 --> 00:00:08,780
So we learned a lot about async code and that is crucial knowledge you need as a Javascript web developer, no way

2
00:00:08,780 --> 00:00:10,980
around that, you need to understand this.

3
00:00:11,240 --> 00:00:14,660
Now with this out of the way, let's have a look at readability,

4
00:00:14,660 --> 00:00:18,590
this code here can be cumbersome to read, right?

5
00:00:18,710 --> 00:00:25,250
If we have such code where we have callbacks nested into each other, like for example here where we have

6
00:00:25,310 --> 00:00:30,620
some callback with setTimeout with another callback again then maybe another function that uses

7
00:00:30,620 --> 00:00:31,870
yet another callback,

8
00:00:31,970 --> 00:00:38,750
then we enter something which has a nickname of callback hell because it gets cumbersome to read and

9
00:00:38,750 --> 00:00:40,880
maintain, it can be hard to track

10
00:00:40,880 --> 00:00:43,040
what's nested in where,

11
00:00:43,130 --> 00:00:48,470
which variables can access where, this is really not nice code to look at.

12
00:00:48,470 --> 00:00:56,000
Now thankfully Javascript has a solution for that and that is the concept of promises. Promises

13
00:00:56,000 --> 00:00:59,660
allow us to write cleaner code because they look like this.

14
00:00:59,660 --> 00:01:03,320
We have some task, then we used the special then keyword,

15
00:01:03,380 --> 00:01:05,620
we then pass a callback to then

16
00:01:05,780 --> 00:01:11,780
but then if we have another task that depends on the first task, we simply add another then block instead

17
00:01:11,780 --> 00:01:13,640
of nesting it into each other

18
00:01:13,760 --> 00:01:16,620
and therefore we have only one level of nesting here

19
00:01:16,670 --> 00:01:22,920
instead of having multiple levels and that makes our code way more readable, let's have a look at that

20
00:01:22,930 --> 00:01:23,880
in practice.

21
00:01:24,140 --> 00:01:28,790
Unfortunately setTimeout and getCurrentPosition have no promise version,

22
00:01:28,880 --> 00:01:30,100
so we can't add

23
00:01:30,110 --> 00:01:36,890
then after that and try to use that promise approach then. More modern web APIs offered by the browser

24
00:01:36,890 --> 00:01:44,180
typically embrace promises and often only support promise syntax but these older functionalities, like

25
00:01:44,180 --> 00:01:47,540
setTimeout which have been around for forever almost,

26
00:01:47,570 --> 00:01:54,160
well these still use callbacks. Now we can actually wrap them into promise support code if we wanted

27
00:01:54,170 --> 00:02:00,200
to and that's what we'll do here to also understand how a promise works internally. Now later in this

28
00:02:00,200 --> 00:02:05,780
course, we'll also see functionalities built into the browser that natively embrace promises.

29
00:02:06,830 --> 00:02:13,930
So let's start by adding a new function here and I'll just name it setTimer, to not to clash with set

30
00:02:13,940 --> 00:02:14,900
timeout and

31
00:02:14,930 --> 00:02:19,230
this can be an arrow function or created with a function keyword, up to you

32
00:02:19,400 --> 00:02:26,060
and here in set timer, I want to get the duration as an argument, I'll need that and now in here, I'll

33
00:02:26,060 --> 00:02:32,470
call setTimeout and pass the duration as a second argument. The question is what do we do in the first

34
00:02:32,470 --> 00:02:34,690
argument? What do we do here?

35
00:02:34,690 --> 00:02:38,740
Well we have to call a function here, as I said there is no way around that but now I have the callback

36
00:02:38,740 --> 00:02:44,440
function here in this separate function and I'll later be able to reuse that in the places down there

37
00:02:44,590 --> 00:02:47,890
to kind of make that easier to work with.

38
00:02:47,890 --> 00:02:54,430
So now we have setTimeout here and now what we have to do or what we can do here is we can build a

39
00:02:54,430 --> 00:02:55,720
new promise,

40
00:02:55,720 --> 00:03:01,510
a promise is in the end an object with the functionality or with the idea of having such a then

41
00:03:01,570 --> 00:03:03,690
method which you can call on it.

42
00:03:03,700 --> 00:03:09,610
So here we can create a promise and you can store it in a constant with any name by calling new promise,

43
00:03:09,610 --> 00:03:15,760
just like that, promise is the constructor function or the class built into Javascript and therefore we

44
00:03:15,760 --> 00:03:23,860
can construct it like this. Now the promise here itself takes a function as an argument, it takes

45
00:03:23,860 --> 00:03:28,150
a function, the constructor takes a function and this is actually a function

46
00:03:28,150 --> 00:03:33,940
the promise API so to say will execute right away when this promise is constructed.

47
00:03:33,940 --> 00:03:39,670
So when we build the promise here, this function which we pass to the promise constructor is executed

48
00:03:39,670 --> 00:03:44,680
right away, it's called from inside the constructor you could say and it's a way for us to configure

49
00:03:44,680 --> 00:03:48,840
what this promise should actually do, what it should wrap itself around.

50
00:03:48,910 --> 00:03:55,390
This function takes two arguments, so this function we pass to the constructor, this function here, takes

51
00:03:55,390 --> 00:04:02,650
two arguments and each argument itself actually is a function. It's a resolve function,

52
00:04:02,650 --> 00:04:08,500
therefore typically called resolve and a reject function, typically called reject but you can name these

53
00:04:08,500 --> 00:04:10,040
parameters however you want,

54
00:04:10,090 --> 00:04:11,810
it's up to you, it's your code here.

55
00:04:13,250 --> 00:04:18,410
Now in the function body, as I mentioned this executes right away when the promise is created. In the

56
00:04:18,410 --> 00:04:22,410
function body here, you can define what should happen

57
00:04:22,640 --> 00:04:28,020
and here I actually want to set the timer, I can access the duration because of the scoping thing you

58
00:04:28,020 --> 00:04:31,220
learned with functions and now the timer is set

59
00:04:31,250 --> 00:04:38,740
when this promise is created. Now in here, we have our async code then, this callback in the timer will

60
00:04:38,800 --> 00:04:41,330
only execute once the timer is done

61
00:04:41,500 --> 00:04:47,590
and after creating this promise, so not after the timer is done, only after creating the promise where

62
00:04:47,590 --> 00:04:53,630
the timer is then kicked off, I will return the promise here so that I can use it wherever I call

63
00:04:53,650 --> 00:04:57,970
set timer, it's returned as a return value of this function.

64
00:04:57,970 --> 00:05:02,770
Now here inside of setTimeout, I will call resolve,

65
00:05:02,800 --> 00:05:10,060
so I'll use this first argument which I said is a function by simply executing it. Now we'll not pass the concrete

66
00:05:10,270 --> 00:05:15,820
function here into promise, instead that is built into the browser. The browser executes this function

67
00:05:15,820 --> 00:05:22,120
for us when it creates a promise and it passes the resolve and the reject functions into this function

68
00:05:22,120 --> 00:05:23,140
here for us.

69
00:05:23,170 --> 00:05:28,870
So the resolve function is coming from the browser, from the Javascript engine to be precise, that is

70
00:05:28,870 --> 00:05:34,930
passing in that resolve function and it's a function which internally will mark this promise object

71
00:05:34,960 --> 00:05:38,680
which is created here in the end as resolved, so as done

72
00:05:38,710 --> 00:05:43,450
you could say and I call resolve here once the timer is done. You can

73
00:05:43,450 --> 00:05:45,600
also pass a value here to resolve

74
00:05:45,610 --> 00:05:51,070
if you wanted to, for example some text but that can be anything, can be an object, can be an array, a number,

75
00:05:51,400 --> 00:05:52,200
whatever you want,

76
00:05:52,200 --> 00:05:57,340
here it's some text, so I pass this to reolve, for the moment I'll ignore reject.

77
00:05:57,430 --> 00:06:00,240
Now we have set timer, now that I'm down here,

78
00:06:00,370 --> 00:06:07,110
we can use set timer, I can call set timer, not set timeout but set timer,

79
00:06:07,110 --> 00:06:11,300
so my own function here, I call this in here and now,

80
00:06:11,330 --> 00:06:17,510
we don't pass a function to set timer because set timer doesn't want the function, it just wants

81
00:06:17,510 --> 00:06:18,720
a duration.

82
00:06:18,720 --> 00:06:23,520
So here we could still pass into 2000 seconds in milliseconds and those will be added to the

83
00:06:23,660 --> 00:06:24,800
wrapped set

84
00:06:24,820 --> 00:06:32,310
timeout. Now set timer does return a promise in the end as my tooltip also shows here, it returns a promise

85
00:06:32,310 --> 00:06:37,620
because that's what I do inside of set timer, I create a promise and I return it.

86
00:06:37,620 --> 00:06:43,820
Now on this promise object, you can call then, you can call this then method and it will basically execute

87
00:06:43,830 --> 00:06:50,760
whenever this promise resolves. Now promise can also resolve more than once, more on that in a second,

88
00:06:50,790 --> 00:06:55,530
for now it resolves once resolve is called here and that happens when the timer is done,

89
00:06:55,530 --> 00:07:01,590
in this case here, that's the logic we wrote in this promise configuring function which we passed to

90
00:07:01,590 --> 00:07:03,460
the promise constructor.

91
00:07:03,630 --> 00:07:08,760
Now in here we also get any data that might be resolved, in this case that will be the text

92
00:07:09,000 --> 00:07:16,260
and then here, I can console log the data here and maybe also the position data here if I wanted to. Now

93
00:07:16,260 --> 00:07:21,930
what you'll see is that if we save that and we reload, if I click track me and I allow this, you will

94
00:07:21,930 --> 00:07:27,330
see it again will take until we have the position and until the 2 seconds are over

95
00:07:27,450 --> 00:07:32,100
but thereafter we see our location but we also see done

96
00:07:32,310 --> 00:07:36,310
and that of course is the text coming from inside my promise.

97
00:07:36,330 --> 00:07:41,920
What we did here is sometimes also called promisifying a built-in API,

98
00:07:42,000 --> 00:07:46,290
I'm wrapping the set timeout API with my promise logic so that I

99
00:07:46,500 --> 00:07:47,040
yes

100
00:07:47,040 --> 00:07:48,890
have some extra effort up there,

101
00:07:48,900 --> 00:07:54,840
it's a bit more complex code but then I can always use the timer here instead of that callback way here

102
00:07:55,170 --> 00:07:58,180
with just my promise

103
00:07:58,210 --> 00:08:06,610
way. I can always call then here now and then have my callback function registered here, timer done

104
00:08:06,650 --> 00:08:11,470
and whilst the benefit might not be super obvious when we just do that for the timer,

105
00:08:11,470 --> 00:08:17,260
imagine we have something similar for get current position and so on and we then just have a couple of then

106
00:08:17,260 --> 00:08:22,990
calls chained after each other as it's called and that's actually what we'll have a look at next.
