All language subtitles for 3. [Dart] Futures, Async & Await

af Afrikaans
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bn Bengali
bs Bosnian
bg Bulgarian
ca Catalan
ceb Cebuano
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
tl Filipino
fi Finnish
fr French Download
fy Frisian
gl Galician
ka Georgian
de German
el Greek
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
km Khmer
ko Korean
ku Kurdish (Kurmanji)
ky Kyrgyz
lo Lao
la Latin
lv Latvian
lt Lithuanian
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mn Mongolian
my Myanmar (Burmese)
ne Nepali
no Norwegian
ps Pashto
fa Persian
pl Polish
pt Portuguese
pa Punjabi
ro Romanian
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
st Sesotho
sn Shona
sd Sindhi
si Sinhala
sk Slovak
sl Slovenian
so Somali
es Spanish
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
te Telugu
th Thai
tr Turkish
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
or Odia (Oriya)
rw Kinyarwanda
tk Turkmen
tt Tatar
ug Uyghur
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated: 0 1 00:00:01,120 --> 00:00:07,780 Now in the last lesson we implemented the geolocator package to be able to fetch our current location 1 2 00:00:08,050 --> 00:00:10,110 both for Android and iOS. 2 3 00:00:10,330 --> 00:00:12,760 And the code is super simple. 3 4 00:00:12,790 --> 00:00:19,480 It's basically a single line that fetches us the current location of the phone depending on which location 4 5 00:00:19,480 --> 00:00:21,160 accuracy we want. 5 6 00:00:21,160 --> 00:00:27,160 However there are two key words that we're using in this code that comes from the documentation for 6 7 00:00:27,160 --> 00:00:30,210 the package that we've never really seen before. 7 8 00:00:30,220 --> 00:00:37,530 So in order to understand this, we have to first learn about asynchronous programming and why it's useful. 8 9 00:00:37,960 --> 00:00:44,330 Now when we're writing code, there are lines of code which take a very short amount of time to execute. 9 10 00:00:44,350 --> 00:00:50,290 For example if we wanted to run a print statement, it's a single line statement prints the word hello 10 11 00:00:50,290 --> 00:00:51,610 world into the console. 11 12 00:00:51,730 --> 00:00:54,910 And this takes fractions of a second to complete. 12 13 00:00:54,910 --> 00:00:58,500 But sometimes there are things that might take more time. 13 14 00:00:58,510 --> 00:01:04,780 For example if we wanted to load a large image from the Internet. Even if we're doing it in a browser 14 15 00:01:04,780 --> 00:01:11,410 and if your internet is slightly slower, you might see this painful loading of the image where it takes 15 16 00:01:11,500 --> 00:01:12,730 absolutely forever. 16 17 00:01:12,730 --> 00:01:18,190 And this is because there's a lot of data that we're trying to transfer through cables under the sea 17 18 00:01:18,520 --> 00:01:25,330 literally trying to get data. And the larger the amount of data the longer the time it takes for it to 18 19 00:01:25,330 --> 00:01:27,240 load. Now 19 20 00:01:27,250 --> 00:01:34,630 consider if we made this function. It's a function that returns nothing. So it returns void but, it has a 20 21 00:01:34,630 --> 00:01:39,810 body that is composed of three steps or three things that it tries to do. 21 22 00:01:39,910 --> 00:01:43,690 And the first thing is to simply print 'Hello moon' to the console. 22 23 00:01:43,690 --> 00:01:45,340 This is pretty quick to execute. 23 24 00:01:45,490 --> 00:01:48,550 So we see the result pretty much immediately. 24 25 00:01:48,640 --> 00:01:54,970 Now the next thing is to load an image from NASA of the moon. And I don't know how often you've 25 26 00:01:54,970 --> 00:01:58,940 done this but they're huge and that can take a long time. 26 27 00:01:59,110 --> 00:02:06,370 But because our function goes from top to bottom, our third Step can't execute until the second step 27 28 00:02:06,370 --> 00:02:07,260 is done. 28 29 00:02:07,300 --> 00:02:14,110 So it's only once this image is loaded that the computer will actually run the very last statement, which 29 30 00:02:14,110 --> 00:02:18,530 is to print the word 'Hello Jupiter' into the console. 30 31 00:02:18,750 --> 00:02:22,420 Now this behavior is what we would call synchronous. 31 32 00:02:22,440 --> 00:02:24,380 Everything happens in synchrony. 32 33 00:02:24,450 --> 00:02:31,080 Step 1 happens, then step 2 happens and only when step 2 has concluded or has finished and we've 33 34 00:02:31,080 --> 00:02:34,910 gotten the image back does step 3 actually execute. 34 35 00:02:35,160 --> 00:02:38,910 Now what would it look like if this was asynchronous? 35 36 00:02:38,940 --> 00:02:47,310 Well step 1 would execute as usual no changes there. But step 2, let's say that we're now loading 36 37 00:02:47,310 --> 00:02:49,740 our image from NASA asynchronously. 37 38 00:02:50,250 --> 00:02:57,180 Well in this case while the image is loading and we're trying to wait on that data to come back, we can 38 39 00:02:57,180 --> 00:03:05,010 already execute step 3. And we don't have to wait for this to finish before we continue in our code. 39 40 00:03:05,010 --> 00:03:08,070 Now why is this actually useful? 40 41 00:03:08,100 --> 00:03:15,630 I want you to imagine that come Monday you're going to work and your boss tells you to get me 100 passport 41 42 00:03:15,630 --> 00:03:16,400 numbers. 42 43 00:03:16,500 --> 00:03:18,540 Get them to me right now. 43 44 00:03:18,540 --> 00:03:25,260 So you have to call up all of the customers one by one and ask them what is your passport number. 44 45 00:03:25,680 --> 00:03:33,180 So you have this checklist and you're going from the top to the bottom one by one calling up each customer. 45 46 00:03:33,180 --> 00:03:36,030 Now it's not so straightforward right? 46 47 00:03:36,050 --> 00:03:39,690 Very few people remember their passport numbers off the top of their head. 47 48 00:03:40,170 --> 00:03:45,510 So you have to start the call ask them for their phone number and then they have to rummage around their 48 49 00:03:45,510 --> 00:03:50,960 house and to actually find their passport to be able to give you that passport number. 49 50 00:03:51,300 --> 00:03:56,880 And this can take anywhere from a couple of seconds to a couple of minutes depending on how well they've 50 51 00:03:56,880 --> 00:03:59,500 stashed away their passport. 51 52 00:03:59,550 --> 00:04:06,870 So what are you doing while all of that is happening? Let's represent this process using a graph. On the 52 53 00:04:06,870 --> 00:04:13,940 horizontal axis is time and we have a couple of units of time, you can imagine each square as a second. 53 54 00:04:13,940 --> 00:04:20,580 Now let's say that it only takes you maybe a second to ask that customer, 'Hey can you give me your passport 54 55 00:04:20,580 --> 00:04:21,330 number?' 55 56 00:04:21,450 --> 00:04:23,640 So your job is kind of done now. 56 57 00:04:23,880 --> 00:04:32,250 The next step is waiting for the user to look for their passport and give you that number. And all of 57 58 00:04:32,250 --> 00:04:39,030 that time you're just sitting there twiddling their thumbs on hold on the call. And you're not really 58 59 00:04:39,030 --> 00:04:40,590 being productive right now 59 60 00:04:40,590 --> 00:04:40,920 right? 60 61 00:04:41,430 --> 00:04:47,430 But once they've given you their passport number you can finally spring into action again and you can 61 62 00:04:47,430 --> 00:04:55,140 go and call the next customer, and then the same process repeats on and on again until you've gotten 62 63 00:04:55,140 --> 00:05:02,160 to the end of that list and you've reached 100 customers. And nobody likes being on hold waiting 63 64 00:05:02,280 --> 00:05:03,000 on a call, 64 65 00:05:03,030 --> 00:05:03,530 right? 65 66 00:05:03,540 --> 00:05:08,790 And if that is the majority of your day then it's not going to feel great. 66 67 00:05:08,850 --> 00:05:12,330 Now you might have realized that there's a different way of doing this. 67 68 00:05:12,390 --> 00:05:18,570 You could in fact have just drafted individual e-mails, say you wanted to keep it personal to be able 68 69 00:05:18,570 --> 00:05:24,660 to persuade your customers to give you the passport numbers, and you could have simply sent these e-mails 69 70 00:05:24,690 --> 00:05:29,110 off to all of your customers one by one. Now afterwards 70 71 00:05:29,110 --> 00:05:32,720 this leaves you free to do any other tasks that you need to do. 71 72 00:05:32,830 --> 00:05:41,200 And as the replies come in, you can respond to them. So you no longer have to be there on the phone waiting 72 73 00:05:41,320 --> 00:05:43,750 for their response. 73 74 00:05:43,750 --> 00:05:51,170 Now if we were to represent this in the same graphical style, then your day might look more like this. 74 75 00:05:51,220 --> 00:05:58,420 You send each customer an individual email but it doesn't really matter how long it takes them to respond 75 76 00:05:58,570 --> 00:06:02,200 because you're able to continue onto the next task, 76 77 00:06:02,200 --> 00:06:08,830 send the next e-mail or do the next thing and they can take their time finding their passport and only 77 78 00:06:08,830 --> 00:06:16,270 once they have their passport number do they respond to you and you get that email response back. And 78 79 00:06:16,270 --> 00:06:22,420 it's in that moment that you can actually act on it and you don't have to be on hold waiting for them 79 80 00:06:22,450 --> 00:06:28,280 to fetch the information you need. So now your day looks more like this. 80 81 00:06:28,330 --> 00:06:35,180 You're using every chunk of the day doing something productive and you're responding to the e-mails 81 82 00:06:35,200 --> 00:06:39,340 that you've sent out as and when the responses come in. 82 83 00:06:39,340 --> 00:06:46,660 So compare these two side by side where in one case you're doing something, waiting, doing something, waiting, 83 84 00:06:46,900 --> 00:06:48,910 doing the next thing and waiting. 84 85 00:06:48,910 --> 00:06:56,440 Well this is synchronous programming. Whereas in the other case you're basically initiating a task and 85 86 00:06:56,620 --> 00:06:58,980 only once that task is complete 86 87 00:06:58,990 --> 00:07:02,260 do you get notified and act on it. 87 88 00:07:02,260 --> 00:07:09,610 So this means that we're able to use only five units of time instead of nine units of time to achieve 88 89 00:07:09,700 --> 00:07:11,780 the same thing. 89 90 00:07:11,800 --> 00:07:16,980 This is the difference between synchronous and asynchronous programming. 90 91 00:07:17,050 --> 00:07:25,420 Now notice how this is all being done by one worker, you. It's not that you have 10 people trying to 91 92 00:07:25,420 --> 00:07:32,140 get 100 passport numbers from 100 customers. It's actually still one person doing that 92 93 00:07:32,140 --> 00:07:39,310 task but it's just done more efficiently because you're letting the customer take their time finding 93 94 00:07:39,310 --> 00:07:45,370 those numbers and only getting your attention once they have the results. 94 95 00:07:45,430 --> 00:07:50,740 So let's build out a real example and take a look at what it would look like if we were to write it 95 96 00:07:50,800 --> 00:07:57,970 in code. Inside your clima project, you're going to right click and you're going to create a new Dart 96 97 00:07:57,970 --> 00:08:02,770 file. And we're going to call this file simply just a scratch file. 97 98 00:08:02,920 --> 00:08:10,210 So it's going to be scratch.dart and it's going to be created inside your main project right here. 98 99 00:08:10,210 --> 00:08:16,060 Now inside this file, this is completely separate from our project, and it lets us test out some Dart 99 100 00:08:16,060 --> 00:08:16,480 code. 100 101 00:08:17,080 --> 00:08:25,170 But unlike DartPad, we're able to tap in to all of the available Flutter and Dart libraries. 101 102 00:08:25,180 --> 00:08:31,300 Now if you head over to this link which will be in the course resources for this module, then you can 102 103 00:08:31,300 --> 00:08:35,590 see that there's a little bit of code that I've already written as some starting code for you. 103 104 00:08:36,040 --> 00:08:41,090 So go ahead and copy all of it and paste it into your scratch.dart. 104 105 00:08:41,740 --> 00:08:50,950 So all that we have here are three functions, task 1, task 2 and task 3. And they're called in sequence 105 106 00:08:51,160 --> 00:08:58,210 inside a function called performTasks. And then in the main function which is our entry point to this 106 107 00:08:58,270 --> 00:09:01,500 particular file, we call performTasks. 107 108 00:09:01,510 --> 00:09:08,770 So right now, you can run this scratch.dart without running any of the rest of our code by simply 108 109 00:09:08,800 --> 00:09:17,720 right clicking on the file and clicking on run scratch.dart. And you should see your console pop up 109 110 00:09:17,840 --> 00:09:24,020 and you can see that this is an isolated file that you can run without having to take all the time to 110 111 00:09:24,020 --> 00:09:27,300 load up the UI and build it onto an app. 111 112 00:09:27,860 --> 00:09:31,250 So this is where we're going to experiment with our Dart code. 112 113 00:09:31,550 --> 00:09:38,600 And you can see that as expected, all that happens is we print T'ask 1 is complete', 'Task 2 is complete', 113 114 00:09:38,660 --> 00:09:39,760 Task 3 is complete.' 114 115 00:09:39,920 --> 00:09:45,350 But the important thing to notice is that they happen in sequence because inside our method perform 115 116 00:09:45,350 --> 00:09:51,100 tasks we said to do 1 then 2 then 3, in this order. 116 117 00:09:51,230 --> 00:09:55,800 These functions are getting called sequentially. 117 118 00:09:55,910 --> 00:10:02,240 Now let's say that task 2 was actually a really time consuming task, like downloading a picture of the 118 119 00:10:02,240 --> 00:10:04,490 moon off the NASA's website. 119 120 00:10:04,490 --> 00:10:07,810 Well let's simulate something taking a long time. 120 121 00:10:08,060 --> 00:10:13,930 We can create a new duration object called threeSeconds. 121 122 00:10:14,360 --> 00:10:17,980 And this is going to be equal to a new duration object. 122 123 00:10:18,020 --> 00:10:20,860 And here we can specify the amount of time 123 124 00:10:20,870 --> 00:10:25,420 so microseconds, milliseconds, seconds, minutes, hours, days. 124 125 00:10:25,510 --> 00:10:29,000 I don't want you guys have to watch this video for days to be to see this example. 125 126 00:10:29,000 --> 00:10:33,410 So we're going to keep it short to maybe let's say a delay of three seconds 126 127 00:10:33,410 --> 00:10:33,650 right? 127 128 00:10:34,130 --> 00:10:41,500 So now to be able to enact this three second duration delay, we're going to use a function called sleep. 128 129 00:10:41,630 --> 00:10:46,270 Now the important thing about sleep is that this is a synchronous operation. 129 130 00:10:46,310 --> 00:10:50,690 So we will have to finish before the next line can be executed. 130 131 00:10:50,690 --> 00:10:57,860 And it takes a single input which has a duration object and we can simply put our threeSeconds in here 131 132 00:10:58,220 --> 00:11:01,850 as the amount of time that we want to pause for. 132 133 00:11:01,850 --> 00:11:10,250 So when we call task 2, it will set a duration of three seconds and it will sleep our program for three 133 134 00:11:10,250 --> 00:11:18,380 seconds. And then and only then, do we get to print 'Task 2 complete' into the console. And because task 134 135 00:11:18,410 --> 00:11:26,080 3 comes after task 2, then theoretically it should also come after three seconds delay. 135 136 00:11:26,090 --> 00:11:29,240 So now let's go ahead and click run again. 136 137 00:11:29,240 --> 00:11:34,280 So notice scratch.dart is currently selected as the thing that we're going to run. 137 138 00:11:34,400 --> 00:11:42,080 And now you can see that task 1 complete, 1 2 3, task 2 task three. So if you're watching this 138 139 00:11:42,080 --> 00:11:47,900 video on double speed or half speed might be a good time to actually put it back to normal speed because 139 140 00:11:47,930 --> 00:11:52,430 I'm going to try and show you what actually happens with these delays. 140 141 00:11:52,430 --> 00:11:58,850 Let's just run that again and notice Task 1, 1 2 3, Task 2 Task 3. 141 142 00:11:59,000 --> 00:12:05,150 So we know that each of these tasks printing a single string into the console basically takes a negligible 142 143 00:12:05,150 --> 00:12:12,140 amount of time. All that's causing the delay is this artificial delay that I've put in here using the 143 144 00:12:12,140 --> 00:12:21,420 sleep method which comes from dart:io. Now because there are a lot of cases where things can take an unpredictable 144 145 00:12:21,450 --> 00:12:28,440 but usually a long period of time to complete such as downloading something or reading something from 145 146 00:12:28,440 --> 00:12:32,850 a file or even doing complex computations, 146 147 00:12:32,940 --> 00:12:35,660 it all takes a large amount of time. 147 148 00:12:35,850 --> 00:12:43,080 And what we don't want to happen is for everything else, every subsequent task, to be held off until this 148 149 00:12:43,080 --> 00:12:44,920 task is complete. 149 150 00:12:44,970 --> 00:12:52,680 So what if we could say that, you know what? Let task 2 do its thing in the background but continue forward 150 151 00:12:52,770 --> 00:12:55,710 and do the things that you can do right now. 151 152 00:12:55,770 --> 00:13:03,510 And once that long task is completed well, then we'll deal with the results once that actually happens. 152 153 00:13:03,510 --> 00:13:09,540 In this case we would be using an asynchronous method instead of a synchronous one. 153 154 00:13:09,570 --> 00:13:12,180 So let's simulate a asynchronous delay. 154 155 00:13:12,720 --> 00:13:15,930 We can do this by instead of using sleep, 155 156 00:13:16,050 --> 00:13:22,470 we can use a method called Future.delayed. So it has two inputs, 156 157 00:13:22,480 --> 00:13:29,170 one is a duration and the second is a computation to run after the delay. 157 158 00:13:29,170 --> 00:13:30,190 This is what we need. 158 159 00:13:30,940 --> 00:13:38,050 So the first input is going to be a three second delay and then I'm going to add a callback to specify 159 160 00:13:38,290 --> 00:13:45,220 what should happen after those three seconds are up. And it's namely creating this result and printing 160 161 00:13:45,220 --> 00:13:47,140 that task 2 is complete. 161 162 00:13:47,140 --> 00:13:49,460 So I'm going to cut that and paste it into that. 162 163 00:13:50,710 --> 00:13:58,540 Now the way that our code is going to run is this is a asynchronous method. And we know it's an asynchronous 163 164 00:13:58,540 --> 00:14:02,110 method because it returns something called a future. 164 165 00:14:02,320 --> 00:14:08,290 So whenever you see a future in the documentation, you'll know that the method is something that will 165 166 00:14:08,290 --> 00:14:16,780 happen asynchronously. And it will delay by three seconds but it will allow other lines of the code to 166 167 00:14:16,780 --> 00:14:18,820 run if they can. 167 168 00:14:18,880 --> 00:14:24,300 Now once these three seconds are up, then it triggers the computation in the callback. 168 169 00:14:24,400 --> 00:14:30,880 And in this case it's to create the result, task 2 data and the print task 2 complete. 169 170 00:14:30,880 --> 00:14:36,250 Now if we run our code again, let's watch the console and see how it works this time. 170 171 00:14:36,250 --> 00:14:41,570 Remember that at the top here where we say perform tasks, I haven't changed that order at all. 171 172 00:14:41,590 --> 00:14:46,060 It's still task 1 should perform, then task 2 then task 3 gets called. 172 173 00:14:46,060 --> 00:14:49,840 But now let's see what happens down here. 173 174 00:14:49,870 --> 00:14:56,750 Task 1 task 3 completed almost immediately, and then task 2 complete after a three second delay. 174 175 00:14:57,250 --> 00:15:00,790 So this is asynchronous programming in action. 175 176 00:15:00,790 --> 00:15:04,370 We saw that because task 2 took a long time. 176 177 00:15:04,420 --> 00:15:10,660 We were waiting for it to happen but we continued. We plowed ahead with the things that we can do right 177 178 00:15:10,660 --> 00:15:11,340 now. 178 179 00:15:11,470 --> 00:15:18,880 And once task 2 completed, it's then and only then, does it actually get executed and printed into the 179 180 00:15:18,880 --> 00:15:22,020 console now. 180 181 00:15:22,060 --> 00:15:28,570 That's all very well and good for things like downloading images from the Internet or doing time intensive 181 182 00:15:28,570 --> 00:15:29,490 tasks. 182 183 00:15:29,770 --> 00:15:36,070 But sometimes we need the results of the tasks to be able to continue to the next task. 183 184 00:15:36,340 --> 00:15:43,440 So for example let's say that our task 3 actually required an input that comes from task 2. 184 185 00:15:43,540 --> 00:15:46,510 So let's change task 3 to take a string input 185 186 00:15:46,540 --> 00:15:55,360 that's called task2Data. And then let's use that inside 3, so task 3 complete with and then 186 187 00:15:55,360 --> 00:16:00,640 we'll add all task 2 data inside this function. 187 188 00:16:00,640 --> 00:16:04,600 Now task 3 relies on something that comes from task 2. 188 189 00:16:04,660 --> 00:16:09,950 So that means we have to return something from task 2 to be able to do that. 189 190 00:16:10,240 --> 00:16:14,820 So let's output a string from task 2 instead of nothing. 190 191 00:16:15,010 --> 00:16:18,720 And we're going to output this result right here. 191 192 00:16:18,910 --> 00:16:22,170 Let's create a new string up here 192 193 00:16:22,210 --> 00:16:23,860 called result. 193 194 00:16:23,860 --> 00:16:32,590 And let's set it to nothing to begin with, but only after our asynchronous method has delayed by 3 seconds. 194 195 00:16:32,590 --> 00:16:37,260 So let's say we're fetching some data from the Internet. Only once that's completed 195 196 00:16:37,330 --> 00:16:43,060 do we assign result to a value. 196 197 00:16:43,310 --> 00:16:52,600 And finally at the very end do we actually return this result as the output of our task 2. 197 198 00:16:52,670 --> 00:17:00,330 So now that task 2 has a output we can assign that to equal a new string called task2Result, going 198 199 00:17:00,410 --> 00:17:05,080 to equal to the output of task 2. And then we're going to use that inside task 3. 199 200 00:17:05,100 --> 00:17:08,420 So task 2 result is going to be the input for task 3. 200 201 00:17:08,930 --> 00:17:16,220 So the entire order of things is task 2 will execute asynchronously so it can take as long as it wants 201 202 00:17:16,370 --> 00:17:17,680 in the background. 202 203 00:17:17,750 --> 00:17:24,680 Now once it's done though, it's going to assign some data to a string called result and then it's going 203 204 00:17:24,680 --> 00:17:29,890 to print that it's completed and also output result. 204 205 00:17:29,930 --> 00:17:36,710 Now at this stage, we're going to take that result and bind it to a new string and then use that as the 205 206 00:17:36,710 --> 00:17:40,530 input for the next step which is inside task 3. 206 207 00:17:40,640 --> 00:17:48,830 What do you think will happen given that we know that task 2 is asynchronous and it can complete at 207 208 00:17:48,890 --> 00:17:54,710 any time at once and our code will actually skip ahead to try and do the things that it can't right 208 209 00:17:54,710 --> 00:17:55,040 now? 209 210 00:17:55,730 --> 00:18:03,800 So if we take a look at running our code, you can see that task 1 and task 3 complete almost immediately 210 211 00:18:04,490 --> 00:18:12,410 and task two is taking its three second delay to complete. But because task 3 relies on some data 211 212 00:18:12,440 --> 00:18:14,250 from task 2, 212 213 00:18:14,270 --> 00:18:20,260 so if it executes immediately then it won't actually have the information to hand. 213 214 00:18:20,690 --> 00:18:24,110 And so that's why we're getting task 3 complete with null 214 215 00:18:24,140 --> 00:18:30,920 at this point because task2Data isn't available until the task 2 completes. 215 216 00:18:30,920 --> 00:18:32,700 So how can we fix this? 216 217 00:18:32,720 --> 00:18:40,820 Well we can make our code actually wait so we know that this is an asynchronous method and we allow 217 218 00:18:40,850 --> 00:18:45,310 other code to continue on and not have to wait for this to finish. 218 219 00:18:45,890 --> 00:18:53,720 But in this case because task 3 relies on this second task to complete, what we can do is we can make 219 220 00:18:53,810 --> 00:18:59,100 our code wait for it to complete before we call the next task. To do this 220 221 00:18:59,120 --> 00:19:02,290 we can change this into a async method. 221 222 00:19:02,630 --> 00:19:06,610 So this is called a modifier and we add it just before the curly brace. 222 223 00:19:06,980 --> 00:19:11,210 By adding that async keyword, we can now have access to the keyword 223 224 00:19:11,210 --> 00:19:12,650 that's await. 224 225 00:19:12,650 --> 00:19:16,160 And we're going to put it right in front of task 2. 225 226 00:19:16,220 --> 00:19:24,790 So before we call task 2, we're going to wait for it to finish. Now inside task 2, we have to make 226 227 00:19:24,790 --> 00:19:28,150 some changes too. Instead of returning a string, 227 228 00:19:28,150 --> 00:19:31,750 we have to return something that's called a future. 228 229 00:19:31,750 --> 00:19:36,250 Now a future is something that will exist in the future. 229 230 00:19:36,250 --> 00:19:43,660 Right now it's nothing because our task hasn't completed. But once our task has completed then our future 230 231 00:19:43,690 --> 00:19:51,810 will be an actual thing like an actual string or an actual integer. Now we have to also mark this method 231 232 00:19:51,900 --> 00:19:59,400 as asynchronous to be able to say that we have to wait for this Future.delayed method to complete 232 233 00:19:59,730 --> 00:20:03,500 before we can output our results. 233 234 00:20:03,560 --> 00:20:11,780 So now with this updated code with our async and await where we're waiting on the parts that need to 234 235 00:20:11,780 --> 00:20:15,870 complete in order to give an input to task 3, 235 236 00:20:15,890 --> 00:20:22,910 now if I hit play and run my code, you can see task 1 complete happens first. And then task 2 happens 236 237 00:20:23,030 --> 00:20:32,510 after a delay and then finally task 3 happens using the data that comes back after task 2 is complete. 237 238 00:20:32,530 --> 00:20:34,620 Now we've talked a lot about futures 238 239 00:20:34,630 --> 00:20:39,510 when we were writing our code in the demo. What exactly are futures? 239 240 00:20:39,580 --> 00:20:43,020 Well they're kind of similar to receipts. 240 241 00:20:43,210 --> 00:20:45,120 Let me explain what I mean. 241 242 00:20:45,220 --> 00:20:49,280 Let's say that you go to the coffee shop and you order a cup of coffee. 242 243 00:20:49,330 --> 00:20:55,150 Now at this point you'll get a receipt with an order number. And you can go away and do something else 243 244 00:20:55,150 --> 00:20:59,510 or check Instagram or check Facebook while your coffee is made. 244 245 00:20:59,530 --> 00:21:02,960 You don't want to stand there waiting for it to be done. 245 246 00:21:03,010 --> 00:21:09,240 So then once the coffee is done, they'll shout for your order, 'Order number 1 please come and collect.' 246 247 00:21:09,310 --> 00:21:17,680 And now you'll show up and you can actually claim your coffee based on your order receipt. That receipt 247 248 00:21:17,950 --> 00:21:21,340 is the same as a future in Dart. 248 249 00:21:21,340 --> 00:21:23,560 It's not the actual thing that you want. 249 250 00:21:23,920 --> 00:21:30,580 It's just a promise that you will get something in the future. If you come from JavaScript and you've 250 251 00:21:30,580 --> 00:21:33,880 heard of promises, then it's exactly the same. 251 252 00:21:33,910 --> 00:21:40,540 It's something that doesn't exist right now but after it's completed its thing, after it's gotten the 252 253 00:21:40,540 --> 00:21:48,040 image or after it's downloaded the text, then your future will actually materialize into a real object 253 254 00:21:48,100 --> 00:21:51,790 like a real string or a real integer. 254 255 00:21:51,940 --> 00:21:54,550 Now you can be more specific with your futures. 255 256 00:21:54,580 --> 00:22:01,360 You can specify that this is going to be a future string or this is gonna be a future integer, and we 256 257 00:22:01,360 --> 00:22:03,800 do that by using an angle bracket. 257 258 00:22:04,750 --> 00:22:12,160 So in this case we can change our date type from just a generic dynamic future to something that is 258 259 00:22:12,220 --> 00:22:13,680 a specific data type. 259 260 00:22:13,690 --> 00:22:16,980 So it could be a future string. 260 261 00:22:17,080 --> 00:22:20,830 So this means that we're expecting a future string 261 262 00:22:20,920 --> 00:22:30,470 when we call this method task 2. And right now if I decide to comment out this line and try to print 262 263 00:22:30,830 --> 00:22:40,320 what task 2 is equal to, then you can see that it's a instance of a future string. 263 264 00:22:40,320 --> 00:22:46,220 It's not an actual string yet. It's only once task two is complete 264 265 00:22:46,290 --> 00:22:54,720 does that future string materialize and change into an actual string. Now asynchronous programming is 265 266 00:22:54,720 --> 00:23:01,440 not the easiest concept to grasp. But I hope through reviewing and re-reviewing this lesson and also 266 267 00:23:01,440 --> 00:23:06,510 completing the modules that are ahead of you, where we're going to be using async and await and 267 268 00:23:06,510 --> 00:23:13,740 futures in a lot more places, you're going to steadily get used to this idea of asynchronously doing 268 269 00:23:13,740 --> 00:23:19,450 something. Instead of doing everything in sequence which is synchronous programming, 269 270 00:23:19,590 --> 00:23:25,440 we're trying to be more efficient with our time or with the computer's time by trying to asynchronously 270 271 00:23:25,500 --> 00:23:32,280 do our tasks so that things don't necessarily happen in the order that we programmed it to, but we end 271 272 00:23:32,280 --> 00:23:36,950 up completing our tasks in the quickest way using the shortest route. 272 273 00:23:36,960 --> 00:23:40,320 So this concept is going to come up again and again. 273 274 00:23:40,320 --> 00:23:46,050 Don't worry if this hasn't completely settled in your mind yet. We're going to be reviewing this a lot 274 275 00:23:46,050 --> 00:23:52,260 more in the future. But in the next lesson we're going to get back to making our app and getting our 275 276 00:23:52,260 --> 00:23:55,020 location data as soon as we load up the screen. 276 277 00:23:55,980 --> 00:23:58,730 So for all of that and more, I'll see you on the next lesson. 31840

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.