1 00:00:06,680 --> 00:00:08,820 - In this section, we're going to see how to use 2 00:00:08,820 --> 00:00:12,360 the async and the await keywords to simplify how we deal 3 00:00:12,360 --> 00:00:15,750 with Promises in our code and in our tests. 4 00:00:15,750 --> 00:00:19,860 So most code these days that uses Promises 5 00:00:19,860 --> 00:00:23,160 they make use of the async keyword to simplify 6 00:00:23,160 --> 00:00:25,140 waiting for the result to come back. 7 00:00:25,140 --> 00:00:27,810 And the async keyword, which is also has a role to play. 8 00:00:27,810 --> 00:00:30,780 So we'll have a look in this section at how we can use async 9 00:00:30,780 --> 00:00:34,770 and await in our code when we are dealing with Promises 10 00:00:34,770 --> 00:00:37,470 and also in our tests as well. 11 00:00:37,470 --> 00:00:40,980 If you want to follow along all the code for this section 12 00:00:40,980 --> 00:00:43,230 is in this folder TestingPromises_AsyncAwait. 13 00:00:45,181 --> 00:00:46,680 Okay then, let's have a think. 14 00:00:46,680 --> 00:00:49,440 So the await keyword. This is the idea. 15 00:00:49,440 --> 00:00:53,310 Here is first of all, the mechanism. 16 00:00:53,310 --> 00:00:55,930 When you call a function that turns a Promise 17 00:00:58,200 --> 00:01:01,390 you can say a Promise.then 18 00:01:02,310 --> 00:01:04,830 and then you can have some code that gets executed 19 00:01:04,830 --> 00:01:06,930 in the then callback. 20 00:01:06,930 --> 00:01:09,870 An alternative to that is to prefix the function call. 21 00:01:09,870 --> 00:01:12,270 You call a function that returns a Promise, 22 00:01:12,270 --> 00:01:15,063 prefix that function call with the await keyword. 23 00:01:15,921 --> 00:01:18,990 What will happen is when you call the function 24 00:01:18,990 --> 00:01:21,840 the await keyword, basically it takes the remainder 25 00:01:21,840 --> 00:01:24,960 of the code in that function from that point onwards 26 00:01:24,960 --> 00:01:28,620 is kind of moved into a giant then callback. 27 00:01:28,620 --> 00:01:33,090 It'll only be executed when the Promise has resolved. 28 00:01:33,090 --> 00:01:35,700 You can also have a catch handler 29 00:01:35,700 --> 00:01:37,620 like a literally a tri catch block 30 00:01:37,620 --> 00:01:39,363 in case the Promise got rejected. 31 00:01:40,770 --> 00:01:43,470 So that's the await keyword. 32 00:01:43,470 --> 00:01:46,800 The async keyword is less important. 33 00:01:46,800 --> 00:01:47,670 You still need it. 34 00:01:47,670 --> 00:01:51,000 Basically if you use the await keyword, the Promises 35 00:01:51,000 --> 00:01:54,180 then you have to indicate on the function itself 36 00:01:54,180 --> 00:01:57,750 you have to prefix the function with the asymc keyword 37 00:01:57,750 --> 00:02:00,240 so that when you code runs, it's kind of, 38 00:02:00,240 --> 00:02:02,730 it knows that it's asynchronous function 39 00:02:02,730 --> 00:02:05,280 and it can then expect the await keyword 40 00:02:05,280 --> 00:02:06,510 inside your function. 41 00:02:06,510 --> 00:02:08,970 So the two keywords go together. 42 00:02:08,970 --> 00:02:11,490 So have a look at this due task function. 43 00:02:11,490 --> 00:02:13,560 We saw this example earlier. 44 00:02:13,560 --> 00:02:17,310 What it does, if you remember I call this function 45 00:02:17,310 --> 00:02:20,310 and I give it a task number, like one or two or three, 46 00:02:20,310 --> 00:02:23,070 and a random number between zero and one. 47 00:02:23,070 --> 00:02:28,070 And inside here, it creates and returns a Promise object. 48 00:02:29,490 --> 00:02:34,490 Inside the constructor I give it some code to execute 49 00:02:34,740 --> 00:02:37,140 a long running task. 50 00:02:37,140 --> 00:02:40,800 This function here will take one to five seconds 51 00:02:40,800 --> 00:02:41,940 typically to execute. 52 00:02:41,940 --> 00:02:45,300 And eventually this function will either resolve 53 00:02:45,300 --> 00:02:49,050 the Promise successfully or reject the Promise. 54 00:02:49,050 --> 00:02:51,150 So if you remember how it worked 55 00:02:51,150 --> 00:02:55,020 if the random number was less than no 0.5 56 00:02:55,020 --> 00:02:56,880 then this function would resolve. 57 00:02:56,880 --> 00:02:58,770 In other words, succeed. 58 00:02:58,770 --> 00:03:00,210 The Promise would succeed. 59 00:03:00,210 --> 00:03:02,100 Otherwise the Promise would reject. 60 00:03:02,100 --> 00:03:03,930 So it was a kind of artificial example 61 00:03:03,930 --> 00:03:07,890 a Promise that will either resolve successfully or reject. 62 00:03:07,890 --> 00:03:10,920 And that Promise object gets returned back to the caller. 63 00:03:10,920 --> 00:03:12,750 Well, here is the caller code. 64 00:03:12,750 --> 00:03:13,950 And what I've done in my caller code 65 00:03:13,950 --> 00:03:16,140 is I've used the async and the await keywords 66 00:03:16,140 --> 00:03:19,590 to simplify how I handle the Promise object that comes back. 67 00:03:19,590 --> 00:03:22,263 So my due task function returns the Promise. 68 00:03:23,160 --> 00:03:25,350 Here's my user interface code. 69 00:03:25,350 --> 00:03:26,640 There was a button click. 70 00:03:26,640 --> 00:03:29,880 When the button gets clicked to kick off a new task 71 00:03:29,880 --> 00:03:31,860 we call the due task function. 72 00:03:31,860 --> 00:03:33,660 This function up here. 73 00:03:33,660 --> 00:03:34,920 We give it a Promise count 74 00:03:34,920 --> 00:03:37,950 and a random number between zero and one. 75 00:03:37,950 --> 00:03:41,370 This function returns immediately with a Promise object. 76 00:03:41,370 --> 00:03:43,770 And what I do then is I use the await keyword 77 00:03:43,770 --> 00:03:46,590 which basically takes the rest of this function here 78 00:03:46,590 --> 00:03:48,900 and puts it into a then callback. 79 00:03:48,900 --> 00:03:50,550 So it won't proceed. 80 00:03:50,550 --> 00:03:52,530 This function won't proceed 81 00:03:52,530 --> 00:03:56,313 until that due task Promise has resolved. 82 00:03:57,180 --> 00:03:58,710 Assuming it's resolved. 83 00:03:58,710 --> 00:04:00,990 Once it's resolved the await keyword 84 00:04:00,990 --> 00:04:03,300 will automatically grab the result 85 00:04:03,300 --> 00:04:05,730 the correct result and assign it into here. 86 00:04:05,730 --> 00:04:07,920 Normally that would be the value that you get 87 00:04:07,920 --> 00:04:09,870 in your then callback function. 88 00:04:09,870 --> 00:04:12,330 So this is basically a then callback 89 00:04:12,330 --> 00:04:13,740 but without the syntax. 90 00:04:13,740 --> 00:04:16,800 Wait for that function to resolve, grab the result 91 00:04:16,800 --> 00:04:19,440 and then assign it to that variable there. 92 00:04:19,440 --> 00:04:22,440 And then display the result on the screen. 93 00:04:22,440 --> 00:04:25,290 The catch handler, there's a tri catch block here. 94 00:04:25,290 --> 00:04:28,170 If you call a function that returns a Promise 95 00:04:28,170 --> 00:04:31,110 but the Promise eventually rejects 96 00:04:31,110 --> 00:04:32,940 then it comes into the catch handler. 97 00:04:32,940 --> 00:04:35,670 That's what happens when you await the Promise 98 00:04:35,670 --> 00:04:37,320 and the Promise is rejected 99 00:04:37,320 --> 00:04:39,150 then it comes into a catch handler. 100 00:04:39,150 --> 00:04:42,780 And this is the error message that would've been rejected. 101 00:04:42,780 --> 00:04:46,260 So up here, when you call reject whatever value you reject 102 00:04:46,260 --> 00:04:47,910 with the error message 103 00:04:47,910 --> 00:04:50,250 that's the value that you catch on here. 104 00:04:50,250 --> 00:04:52,080 And then we display that on the screen. 105 00:04:52,080 --> 00:04:56,790 So in our user interface code we can use the await keyword 106 00:04:56,790 --> 00:04:59,730 to wait for the Promise to be resolved 107 00:04:59,730 --> 00:05:01,710 or to catch the exception if it isn't. 108 00:05:01,710 --> 00:05:04,320 When you use the await keyword here 109 00:05:04,320 --> 00:05:06,690 you have to prefix the function with async. 110 00:05:06,690 --> 00:05:08,850 If you didn't you'd get an error, 111 00:05:08,850 --> 00:05:10,830 you can't use the await keyword here, 112 00:05:10,830 --> 00:05:13,020 unless you've already told JavaScript 113 00:05:13,020 --> 00:05:14,920 that this is an asynchronous function. 114 00:05:16,770 --> 00:05:19,890 So we can use async and await in our code. 115 00:05:19,890 --> 00:05:22,980 We can also use those keywords in our tests. 116 00:05:22,980 --> 00:05:26,790 So I've got a test with two functions. 117 00:05:26,790 --> 00:05:30,990 A test function that will ensure that a task resolves. 118 00:05:30,990 --> 00:05:34,170 If I give it a value less than an 0.5. 119 00:05:34,170 --> 00:05:35,730 So similar kind of idea. 120 00:05:35,730 --> 00:05:38,670 I call my two due task function 121 00:05:38,670 --> 00:05:40,380 and I give it a value less than an 0.5. 122 00:05:40,380 --> 00:05:43,620 So it should resolve as opposed to reject. 123 00:05:43,620 --> 00:05:45,360 Await resolution. 124 00:05:45,360 --> 00:05:49,890 So basically this code here gets moved into a then block. 125 00:05:49,890 --> 00:05:51,060 It waits for that function to, 126 00:05:51,060 --> 00:05:53,280 for that Promise to be resolved. 127 00:05:53,280 --> 00:05:55,710 Assuming that it is resolved successfully, 128 00:05:55,710 --> 00:05:58,530 it'll grab the result and assign it to that variable. 129 00:05:58,530 --> 00:06:01,770 And then I can just check that's the result of the resolve. 130 00:06:01,770 --> 00:06:03,930 I can check that the result of the Promise 131 00:06:03,930 --> 00:06:05,223 is the correct string. 132 00:06:06,600 --> 00:06:08,790 And don't forget that if you use the await keyword 133 00:06:08,790 --> 00:06:10,710 in a function or a Lambda 134 00:06:10,710 --> 00:06:14,430 you have to indicate that this function or Lambda is async. 135 00:06:14,430 --> 00:06:16,800 If you have await here, you have to have async 136 00:06:16,800 --> 00:06:17,823 before the function. 137 00:06:19,110 --> 00:06:21,600 And the next example's similar 138 00:06:21,600 --> 00:06:23,640 but it's checking for failure. 139 00:06:23,640 --> 00:06:27,210 So I'm gonna pass in the value 140 00:06:27,210 --> 00:06:29,640 equal to or greater than 0.5. 141 00:06:29,640 --> 00:06:31,650 So when I call the due task function 142 00:06:31,650 --> 00:06:34,980 this value here should, according to the logic in there 143 00:06:34,980 --> 00:06:38,760 that should cause the Promise to reject. 144 00:06:38,760 --> 00:06:42,960 So I call it await in the chance that it might resolve. 145 00:06:42,960 --> 00:06:45,420 It doesn't resolve, it rejects. 146 00:06:45,420 --> 00:06:47,700 And therefore, cause the catch handler. 147 00:06:47,700 --> 00:06:50,730 And this error message here will be the error 148 00:06:50,730 --> 00:06:52,980 that this then rejected with the error screen. 149 00:06:52,980 --> 00:06:55,440 So we can just check that the error screen 150 00:06:55,440 --> 00:06:57,390 is the correct error. 151 00:06:57,390 --> 00:06:59,320 And then just one reminder 152 00:07:00,690 --> 00:07:04,740 expect .assertions(1) is to ensure 153 00:07:04,740 --> 00:07:07,320 that we don't get a false positive. 154 00:07:07,320 --> 00:07:08,880 Just to remind you what could happen 155 00:07:08,880 --> 00:07:10,290 if we weren't careful enough. 156 00:07:10,290 --> 00:07:14,490 Imagining that my code here in due task was buggy. 157 00:07:14,490 --> 00:07:17,970 And instead of rejecting when it should do 158 00:07:17,970 --> 00:07:19,380 it actually resolved. 159 00:07:19,380 --> 00:07:22,860 In which case it wouldn't go into the catch handler. 160 00:07:22,860 --> 00:07:24,780 So it wouldn't execute this expect 161 00:07:24,780 --> 00:07:25,800 and that wouldn't be right. 162 00:07:25,800 --> 00:07:26,970 It should have done that. 163 00:07:26,970 --> 00:07:29,430 So when you say expect one assertion 164 00:07:29,430 --> 00:07:33,000 what we're saying is there must be one expect executed. 165 00:07:33,000 --> 00:07:36,393 It must go into the catch handler otherwise it'll fail. 166 00:07:37,260 --> 00:07:38,093 Because it should do. 167 00:07:38,093 --> 00:07:39,580 It should go into the catch handler 168 00:07:40,878 --> 00:07:42,928 and that's how we can verify that it did. 169 00:07:45,240 --> 00:07:49,320 One last thing to show you is you can also use async08 170 00:07:49,320 --> 00:07:52,920 in conjunction with the results and rejects matches. 171 00:07:52,920 --> 00:07:53,820 Have a look at this code here. 172 00:07:53,820 --> 00:07:55,370 This is a different test suite. 173 00:07:56,250 --> 00:07:59,310 I've got a task which resolves correctly 174 00:07:59,310 --> 00:08:01,800 if the value is less than not 0.5. 175 00:08:01,800 --> 00:08:05,070 So if you remember the resolves matcher 176 00:08:05,070 --> 00:08:07,590 expect call the function. 177 00:08:07,590 --> 00:08:09,540 That function returns a Promise. 178 00:08:09,540 --> 00:08:12,150 Verify that the Promise resolves 179 00:08:12,150 --> 00:08:15,243 and that the result of that Promise is this. 180 00:08:16,260 --> 00:08:18,390 So the await keyword here, 181 00:08:18,390 --> 00:08:21,780 well, what actually happens is from there to there 182 00:08:21,780 --> 00:08:23,520 is a Promise object. 183 00:08:23,520 --> 00:08:27,810 So we basically say await on that Promise object to finish 184 00:08:27,810 --> 00:08:30,600 before our test function returns 185 00:08:30,600 --> 00:08:34,920 to prevent the test function from returning too early. 186 00:08:34,920 --> 00:08:38,730 And similarly here call the due task function 187 00:08:38,730 --> 00:08:41,193 with the value that we expect to be rejected. 188 00:08:42,750 --> 00:08:44,100 So that returns to Promise. 189 00:08:45,390 --> 00:08:47,820 Verified that the Promise was rejected 190 00:08:47,820 --> 00:08:51,060 and that the rejection error string was that. 191 00:08:51,060 --> 00:08:54,810 And again, from there to there is a Promise. 192 00:08:54,810 --> 00:08:57,210 So we await completion of that Promise 193 00:08:57,210 --> 00:08:59,523 before the test function returns back to test. 194 00:09:01,157 --> 00:09:03,360 Okay, so we should run those tests. 195 00:09:03,360 --> 00:09:07,830 I can just run all tests in this demo. 196 00:09:07,830 --> 00:09:12,180 So in this demo I have all the tests we've just mentioned. 197 00:09:12,180 --> 00:09:15,600 A test where we use the async and await keyword 198 00:09:15,600 --> 00:09:16,740 first of all. 199 00:09:16,740 --> 00:09:19,590 And in another test suite where we use the resolves 200 00:09:19,590 --> 00:09:21,583 and the rejects matchers. 201 00:09:21,583 --> 00:09:25,110 So I have two test suites covering the four tests altogether 202 00:09:25,110 --> 00:09:26,640 that we've just gone through. 203 00:09:26,640 --> 00:09:28,740 I can run all of those tests to verify 204 00:09:28,740 --> 00:09:31,260 that they all give me the correct result. 205 00:09:31,260 --> 00:09:33,930 So I can do that like so jest. 206 00:09:33,930 --> 00:09:36,630 So it'll run both test suites. 207 00:09:36,630 --> 00:09:38,940 One test suite that basically checked 208 00:09:38,940 --> 00:09:42,120 the await async keywords on their own. 209 00:09:42,120 --> 00:09:44,760 And then the second test suite that checked the rejects 210 00:09:44,760 --> 00:09:47,460 and resolves matchers. 211 00:09:47,460 --> 00:09:50,640 Now, because there's an element of a time of delay going on 212 00:09:50,640 --> 00:09:54,003 it did take a little while to complete, but there you go. 213 00:09:54,840 --> 00:09:57,330 So we have successfully used and checked 214 00:09:57,330 --> 00:09:59,790 for the async and await using Promises. 215 00:09:59,790 --> 00:10:01,950 And then we've used the resolves and rejects 216 00:10:01,950 --> 00:10:04,643 matchers as well in conjunction with the async 217 00:10:04,643 --> 00:10:05,970 and the await keywords. 218 00:10:05,970 --> 00:10:08,430 So generally when you work with Promises 219 00:10:08,430 --> 00:10:11,340 I would recommend using async and await. 220 00:10:11,340 --> 00:10:14,310 It's easier than having then callbacks and cap callbacks. 221 00:10:14,310 --> 00:10:16,680 You have a more linear flow through your code. 222 00:10:16,680 --> 00:10:17,930 Makes it easier to write.