Actually Understanding Asynchronous JavaScript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so I think there's like several levels of understanding a singers JavaScript there is you know a level one is I don't which is like a place right like I start as a ruby developer when I switch to like JavaScript like I just literally didn't know why that variable was undefined I literally just called beforehand cuz I didn't get how many if it worked then there's like level two which is I think where a lot of us live which is I don't really understand how it works but if I know I thought I use dot bind to this and throw everything in that callback everything's fine right and I lived there for a really long time and then I got this like unpaid gig where I had to write documentation for Mozilla and I had to like actually understand how it worked I like figure it out like what the browser was doing it of the hood and once I got there then like everything became a little clearer so my job in the next 25 minutes is to kind of compress that down and get try especially I can to get you all the way there you ready all right so my name is Steve which I feel like we covered so I don't really need to go into that I live in Colorado and I don't know how to ski those are the important details there I work at place called Sun grid if you've ever taken an uber or late night bid on something on eBay and got an email about it we sent you that email along with us several other billion emails every day I actually work on a WYSIWYG HTML editor that makes HTML email so like Ben's talked about 1999 I lived there asking me ask me about Outlook later I am perpetually working on a book an electron I finished writing in October and then in May electron two came out so I updated it and then they announced the electron 3 beta so it's just never going to be done so yeah cool when I kind of tweeted earlier today I like those cool signs outside and my friend Brian Sinclair said that I should rename the talk asynchronous JavaScript actually explained or Ajax was short I told him I was gonna use in this talk and this is what he said so the important note here is that you should outsource your conference jokes to your friends and then everyone thinks you're funny when really you just have funny friends so we're going to talk about a little bit with about our relationship with asynchronous code I guess that starts out with like what does asynchronous really mean and we're gonna find out the only way that you can truly learn about anything which is to torture some metaphors so we're gonna run some errands and we're gonna learn about synchronous code in the process maybe so two things I need to do I need to pick up a prescription from the pharmacy and I need to go to Safeway and that's like I don't wear glasses but that's the best I could do so step one if I was doing this synchronously I would take my prescription I'd go stand there and wait in line as somebody wanted to argue with the pharmacist about what their insurance didn't did not cover as if that was gonna help anything and then finally I would pick up my prescription and I would go along my merry way I finished one task and I'd go on and I'd go down to Safeway do y'all have Safeway in Omaha what's the grocery store around here what's that cool I didn't I I didn't have a safe way to move to Colorado so that's a new thing for me and I can go I give them some money and in exchange I get some carrots or a carrot and I move along my it's just expensive these days life is really hard I go ahead and now I want to run them asynchronously so what is the kind of difference they're the whole thing of what they synchronous stuff is like a non-blocking thing I almost liberated a balloon there where I can show up again and I'll drop off my prescription and then while they're handling all that were prescription then I will go down and I'll go shopping I will shoplift a carrot I got 25 minutes I can't do every animation every time everyone and that eventually I'll go ahead and pick up my prescription and I'm good to go so now it's a synchrony is almost a form of concurrency right I can kind of do two things at once while I'm waiting for one other thing and go do something else right there are some like caches here which is that functions in JavaScript run to completion so again let's go back to our metaphor I go ahead I drop off my prescription head on over to Safeway and I flash them some money I get my carrot and while I'm shopping my prescription is ready now I can't just like leave the grocery store with this carrot because that is illegal right they will prosecute me they have signs that say this I can't stop what I'm doing I have to finish what I'm doing a Safeway you know flash some money received my carrot and then I can go ahead and I can pick up my prescription right so we have to finish what we're doing in JavaScript so just because this is actually this is the holy javascript a single-threaded kind of thing which is half true but it actually solves a lot of concurrency problems where like you're gonna finish the thing you're doing so if new information comes in or something else happens it can't really change the state of what you're currently working on which solves the whole series of problems for us and it's great cool all right so we've got some metaphors in place what does that run to completion look like what does it mean to run to completion really means three things one is that an error is thrown and not caught that will like blow everything up and you're done two is that you return from the function which is you complete it and three is there's no more code in the function right and so in JavaScript that returns undefined and other languages it might return the last thing so on and so forth all right so then the next question is why do we have why is asynchrony important why is non-blocking important with building user interfaces most frameworks of building user interfaces have some idea of a synchrony because it's important if you're going to have a user interface multiple things are probably going on so here's an example we've got a little this little box that I made that's very cool I'm selecting some text if I hover over the buttons I'll get some CSS hover events everything's really great I hit that start blocking button and you'll notice that my animation stopped all my CSS transitions stopped I can't select any text like game over how did he block the browser this is how I block the browser yeah open source I'll put it on NPM later you can all install it it'll be great I pretty sure it's secure cool all right so now we have like some of the basics of why it's important in what it means how does it actually work so asynchronous JavaScript is based on events the same events if you've you know done any jQuery or just vanilla JavaScript with the Dom that same idea of events that is for every like promise library you've ever used or observables or whatever under the hood there's probably an event happening right a lot of times we use abstractions to hide a lot of that we don't have to deal with it but there it is under the hood that's kind of a level that we're going to talk about today all this stuff happens under the hood because all the fanciest asynchrony library that you've ever used it's still based on a few simple core language features so we'll kind of we're gonna explore those today so all right how does synchronous code work right it's kind of it's like a Tarantino movie we're like jumping back and forth it's okay it's intentional so in you know programming we have this thing called the call stack right and that's keeping track where we are in the execution of our program so here's my here's my program I have an array of possessions I have a life savings it's 25 25 what I don't know and but that's it I'm a millennial that's all I have and I got two things I'm going to do is I'm gonna go grocery shopping and I'm gonna buy some when I'm grocery shopping I'm gonna buy some vegan ham so that like we'll have those different functions that would run if I have enough life savings whatever unit that is I will purchase some vegan ham if not I will throw an error saying I don't have enough money and then we will execute the go grocery shopping function which will execute the by beak and hand function and so on and so forth so what does that look like in the call stack we kind of start the program at the top level okay we declared a bunch of functions but the first function that we execute is go grocery shopping cool that immediately calls buy vegan ham we run through that you know I decrement my life savings I push vegan ham into my array of possessions who amongst us hasn't done that and that finishes up the vegan ham function which then brings us to the end of the go grocery shopping function which like finishes up my program now if it's in the browser it's just gonna chill out and wait for other events if it's a node program it would like we'd be done we'd be kicked back out to bash need alright let's just go a little bit I'm also gonna buy some organic almond milk which is very expensive it is 20 of whatever which is gonna cause a problem when I to go to pick up my vegan ham because I'm not gonna have enough life savings anymore for this right so this is gonna be a little bit different so we'll run through this code again the first coat the first piece of code that we actually excuse go grocery shopping which then calls the buy organic almond milk function neat that executes just fine we run that to completion cool now we're going to go grocery shopping oh now we're going to the next function which is buy the vegan ham things are gonna be really good here that's gonna blow up that's right I use that thing in keynote and I'm not even ashamed of myself and it's going to blow up the entire call stack you're like this is interesting you've seen the call stack before it's just like you don't have like fond and warm fuzzy feelings about it cuz this is usually the context in which you see the call stack is when something has blown up right they'll show you everything that happened between where that initial fire started and all the ways that escalated up cool alright that's synchronous code how does asynchronous stuff work so the a singer stuff goes on this thing called the event queue which we kind of check repeatedly with the event loop like remember I said when you're in the browser like the page doesn't close and your JavaScript stops running right that would be bad I mean you could probably do that it'd be kind of cool but it's probably bad it kind of triggers don't wait for like click events or all sorts of other events that could happen so we've got this cue with the call stack it is first in lat first-in first-out right this is whatever I'm not I'm not live computer science in terms you all right like we started we you know we started from the the top thing and work our way down this one we will take whatever came first like a normal line and we'll ahead we'll handle the first one then the second one and then finally the third one cool where it gets a little more interesting is how these two interact which is we can only check the event queue with the event loop whenever the call stack is clear so anything that's in the queue will wait until the call stack is clear if it's clear it can kind of move over because we keep checking the queue whenever the call stack is emptied more stuff comes along if it's empty just go handle it in the order that it was received all right neat so I lied to you at the beginning of this talk which is always fun to open with lies it's a way to build trust and friendship amongst your audience there's no such thing as asynchronous JavaScript which is also a lie for the first 20 years of JavaScript there was no such like there was no mention of asynchrony in the JavaScript spec javascript was asynchronous as Ruby and Python and all the other languages where you didn't have to deal with asynchronous code right in the es2015 spec there's this little thing about a job SKU that has to do with promises but let's just like live like in a world where the specs still doesn't say anything about asynchronous code because like generally speaking like we had promised polyfills before that was in there let's just make that little detail doesn't exist and just go with the idea that there's no such thing as a synchronous JavaScript you're like how am I gonna accidentally accidentally understand the thing that doesn't exist I don't know so most of the things we think about is asynchronous actually comes from the environment right what is the environment well it's like whatever browser you're running in or node in this case so the lack of a browser but like v8 in that case and in the widow object you've got like the whole dom which is separate from javascript right there's a set of API is that you can use and you call it with JavaScript methods but it's separate from the JavaScript programming language itself and then we have this other thing called the behavior object model or the bomb which is all the things that we think are part of the JavaScript language but if you read the ACMA scripts spec aren't in there at all and so it's set timeout set interval it's set interval XML HTTP request fetch requestanimationframe all those very like browser specific ones some of those reported over to node not all of them but they're not necessarily part of the script language and most of them are implemented in C or C++ if you just do like set timeout in chrome dev tools it'll just be like native code it won't show you the function definition like a would for a function you wrote because it's actually not in JavaScript right so there's there's no such thing as asynchronous JavaScript but like let's just ignore that so one example I like of asynchronous call is set timeout everyone's like friend which will in this case it takes a function that you want to call and then some amount of time that you want to wait before that function is called and it's very like I think a common mistake is that a lot of people think that this will execute in 500 milliseconds that's not true it will be added to the event queue in 500 milliseconds right which if there's stuff in a call stack it's gonna sit there and wait until that's clear right we just we saw that earlier so it's like at least 500 milliseconds that's why if you're trying to do like smooth animations set timeout or set interval and not your friend stuff like requestanimationframe is probably a better bet because this is at least 500 milliseconds so if you're trying to get like buttery smooth stuff that's not gonna work so here we are we have stuff in here we have to throw a set timeout that's gonna get who's gonna wait for that hundred milliseconds and then our buddy's gonna sneak in that function that has that like infinite loop of while true it's gonna sneak in there which is yeah after like a thousand milliseconds that's gonna be added to the event queue and never called ever right so you'd be like hey one if you want to try this at home a really great example of a blocking function one of the last like true blocking functions in JavaScript that you can use is alert so you can do something where it like sets the timeout and then immediately calls an alert for light you say set timeout like one one second later you know you then you fire an alert and then go like make a sandwich or something right it will block that code until you dismiss that alert and then everything on the event queue will begin to get cleared out so it's a really great way to highlight visualize that and you might be like neat you made that like I don't have infinite loops in my code yes what you think I don't have infinite loops that I know of in my code is usually what that means but there's still cases where it doesn't have to be infinite to be problematic so if you have any kind of expensive test we've all seen that thing in like Chrome or Firefox there's like this script is taking longer than expected do you want to kill it or keep waiting right that is something that has taken too long and somebody wrote that line of code me but like there are ways that you can actually take advantage of the event queue in the event loop to make this easier so you can use timers or you can how to make your pages more responsive with one weird trick so all right here's a contrived example we have some expensive batch tasks that's gonna iterate through 10,000 a million records and do something expensive each one it could even just be updating the Dom right so what we could do is we could iterate through this really really large array and do stuff but that's going again like block up the works so like we'll keep going in there they'll stack up and stuff will end up in the queue and never really like get executed right he'll just wait a click events also they'll basically have the same effect of when we saw the animation stop and the CSS hover stop it's not great right what we could do is we could go ahead and like basically take advantage of the event queue to split it up which is like we're going to put each individual one on the event queue which means stuff like click events and also to hover away other events can kind of get in the middle of that line so we can have a quick event some something expensive can get in there and animation can happen we can start to interleave stuff that the user did with stuff that are really expensive function is doing right and yes you could also like pull it off to a web work into a and maybe just do it a server-side right yeah all is it possible but this is like you know one that I could fit on slides that's great so now it'll go through all those things neat all right now the most common way that we're going to use asynchronous JavaScript is likely that we are going to make an AJAX request right and you have probably never written this and as I go through this code you'll see why because it's terrible and why would you do this but the way it works is you make a new xmlhttprequest you have a load event you have an error event and then you open it with the method and the endpoint and then you send it and then that load event will trigger or the error event depend how this goes right so that's how just vanilla xmlhttprequest works most of us use something like X cos or jQuery dollar sign at Ajax something else along these lines but out of the hood that is the kind of like native browser implementation so one pattern for doing this is the callback pattern right and callbacks aren't anything special it's the nice part about first-class functions in JavaScript is that functions could be passed as arguments to other functions exhibit joke cool and so here's an example we can pass in a function as an argument and then we can call it inside of that function like this is a silly example of a callback pattern so let's take that XML from before and we're going to refactor it we're like I took out error we'll just we'll do what that separately so what are the kind of pieces that can change here well the callback when it loads write the method and the end point so we take all those and we go ahead and we just make a new function where we're going to pass those in do a little copy/paste action because like that's how you write code and you just take the parts they're gonna change and replace them with the arguments that pass in right now we can go from this big mess of code to this you want to use it again you don't have to write that code all over again you just use your new callback pattern right you've effectively invented a very bad version of dollar-sign Ajax in jQuery we have no we have no error handling in that so we need an alternative approach now jQuery does it differently than no did it right and we can kind of look at some of those right which is we had that load but what about when things go wrong so we can we in have the callback there if if an if we have like let's say greater than the 400 we'd say like hey this didn't go well otherwise we're gonna do the right thing so we'll have the error callback oops well have the error callback and the regular callback and we'll be able to like have both right node handled this a little bit differently so here this is the jQuery model will pass in hey here's a callback if things go well here's a callback of things go poorly write the node way of handling this is to go ahead and have one callback where the first argument always be an error the second argument will be or further arguments are the good stuff right and then going ahead if things go poorly we pass the error and it's the first argument if things go well it passed the right stuff and it's the second argument so then we do something like this to have our error and good state cool callbacks have problems you can usually only do one thing with that date like one step function is over once it's run to completion you don't have any of those variables anymore they're now out of scope you can't really store the results anywhere because of that like you can get really creative what the window object please don't you have to be creative with event at hand with error handling we saw that and basically it's like with that it's like you're putting some function that you wrote onto the event queue and saying hey whenever that comes back here's a function go call it if it's something like billing or something like that you don't know that somebody else who have you handed that function to isn't gonna call it like six times right you've given that function away it's outside of your hands you've given it to the event queue and you hope for the best and then like there's always that like pyramid of doom right if you need to like go ahead and like okay we need that day they'll call the second one to call the third one right and so this is like I want to get all of the members from all the organizations that I'm in on github like you get that like pyramid of doom as your code gets just scooching further and further to the right and now you have this moment of the scroll horizontally in your text editor you know something has gone terribly wrong cool like I could get like that code that should show you could get worse that's fine name like the fellow members of one organization if I wanted to find all the members from all the organizations this you can just see that this pyramid just gets worse and worse and worse so in like more and more cases there's libraries like the async library it's velbon MPLS right but there's probably of other tools in language now one of this just promises and so jQuery supports promises where you can actually just take make an asynchronous request and you can store it into a variable and promises like jQuery aren't technically promises they are deferred because they don't follow the promise spec all right you just call them all Venables if you want to seem cool we're just going to use the promise the word promise is a generic thing today so you can say hey I basically you back an IOU when you called asynchronous request right it's like yeah I'm gonna hit that endpoint I owe you there's eventually I'm gonna have something back from the server or an error you're like cool when that comes back then go do this other thing right and whatever that payload of data is will get passed into that function that you pass in and what's cool is that it solves a lot of the problems of course we can do multiple things over and over and over again and you can also do cool stuff like chaining promises alright so here we can have the promise that resolved just immediately creates a promise that has resolved right so this will resolve with two in that data so you can be like okay cool console.log it or you can add one and that will return a new promise every then returns a new promise with the return value of the previous function right so here we'll have that too then we'll add one now it's three x two it's six second taking the second powers 36 so on and so forth right you can take that original one you can store it and have it back again as a two you do a lot of really interesting because instead of giving away that function where you don't have a control anymore you actually are in control you have it all and you on your side of the equation and you can do interesting stuff with it as you need to all right and promises like love them or hate them are also interesting because a lot of other really cool stuff in the language like observables and async await involves promises as well under the hood right so you could be even be using promises in cases that you don't know you're using promises all right cool so here you've just needed more practical example here's our Dallas injection before we can have a function called render post which will receive a post and like make some markup for us and then we can every time we have the request we can map it through that and we get much cleaner code we're like avoiding that like pyramid of Doom that we had before which is very cool so then we can like go ahead and like do something like add them to the page there is a problem though which is we do need to solve for that error stage right here we'll throw a new error in the middle that's not great because the promise is counted as rejected so we do in that case is that we catch errors at the very end if you don't catch them at the very end then like other stuff can go wrong so you usually keep your catch if any promise along that entire chain rejects you can handle it somewhere along with you oh sorry we couldn't get your stuff or whatever most of time we're consuming promises sometimes we have to make them if you have yeah that's problematic if you have to make them right you just use the new promise constructor which takes a function which passes in resolved and reject which are also functions and basically if good things happen you call resolve with it whatever that data was passed the good things in they'll get past the dot then if bad things happen then you'll go ahead and reject and everything will work along those ways so let's go ahead and refactor that callback pattern real fast all right so this is the callback 1 we're simply going to return a new promise where we'll have the resolving the reject well can I take that code where it cut and paste it right and now instead of calling the callback where you get rid of that and we will reject in the case that it didn't go well and we will resolve it in the case that it did right and there we took a callback pattern I'll show it to you again we'll take that callback pattern we turned it into a promise pattern that's it right that's all the black magic of like making promises which in listen we could library you don't have to usually you consume promises like 99% of the time but occasionally if you don't have it's like oh this is giving me callbacks I don't like callbacks cuz I watch the talk and he said they're problematic and now I use promises you can actually just wrap anything in a promise as well there's some cool things like promised at all which will basically take an array of promises and if they all r is a like to now you can set a whole battalion of network requests and if they all come back then you can go to a thing there's promised outrace which I have never actually found a reason to use sorry and that will actually come back with the first one right so the first promise that resolves you'll get that one I leave it as an exercise of the razor reader so promises always run to completion that was a lie also well you'll knows have an asterisks asterisks will create you a generator function and generator functions can actually kick back control a number of times this yield instead of return every time we yield we go back to the scope that called it we couldn't go back in the call stack in that case so yield one two three I can you know make a new generator and I can say dot next the first time I'll get one the second time I'll get two 13:03 eventually the function is actually to completion and so we can kind of like leave a function and come back in which it's not kind of neat the really interesting part which again is super confusing to see on a slide so I apologize to these slides in advance I'm going somewhere that I promise is that you could actually pass data back in so here's a function where we will actually yield out that argument that's passed in and then come back in and store something into a constant so we'll pass in a originally we will go ahead and will yield a and then when we come back again we'll actually store the next thing and B and then finally we have a plus B and so the way that works is like we call it we'd get back that a then we call it again we pass in the two and then finally we get the get both of them combined so we passed in something we left the function we came back in with more stuff we got stuff and so it's kind of interesting because like sometimes we saw with that like multiple callbacks before like you need to like get some information and do some more stuff like this kind of interplay of like thank you for some information let me give you some and like we can like build more complicated asynchronous flows is really interesting so sometimes we need to wait for a bit of information and now we have the ability to pause functions and come back to them later with more information so hey to put stuff on the page I need to fulfill this network request I have to wait for that so why don't you let me do something else like handle a click event and when we get back to the network we'll come back in and pick up where we left off all right so you could write some terrible code like this this is using generators you can see I'm making two API requests I have this like request thing which is just by using it Ajax function with the promise that I made before and it's kicking off the generator every time with the it next and so I yield each time which is I leave that function as I wait for the network request to finish and every time I get the next piece of data I can store it a constant and move along and have to do this like kind of interesting stuff here where I've got the function main like a messy programmer or something and then I've got these yields in there they seem interesting I've got this like part right here where I'm kicking off the generator again which has to kind of be in a global scope which is gnarly and then to kick off my entire program I have to do this this is kind of gross it works but it makes me feel bad inside but interesting fact if you take promises and then you match them with you mixing with generators and then you just throw in a bunch of syntactic sugar to make believe you don't just see all that code is just show you you know you get a single wave that's all a single wait is its promises and generators and some black magic and a curtain so you don't see any of the dark that's actually going on in other things so yeah we bring them together here we can go and we can we have this code from before and we just say hey this is an async function and we replace those yields with a wait all of that sadness is gone error handling you get the try cash that's in the language which is fine and that again that Ajax function is the same promise one that was based on the callback one that we looked at earlier in this talk right so you can do a whole bunch of really cool stuff I wanted to get both simultaneously I can use promised at all in an async function and await it because it's all promises and all generators under the hood so none of this is sorcery it's just JavaScript which arguably is sorcery and all the other like crazy things that you've like read about in like JavaScript legally or hacker news or whatever is mostly some combination of events promises and callbacks right and so there are a lot of other interesting patterns out there they're all based on this and like once you have these foundations like kind of like we've wrapped your mind around them like I think you're ready under like they're it's not like oh this library I don't know how it works like you now have like all the foundational pieces in place so yeah all that kind of fun stuff is based on literally stuff that we just spent the last 25 minutes and 30 seconds and 177 slides on so thank you very much [Applause]
Info
Channel: Coding Tech
Views: 22,288
Rating: undefined out of 5
Keywords: javascript, asynchronous programming, asynchronous, asynchronous javascript
Id: 8LCx9Dir8BU
Channel Id: undefined
Length: 29min 8sec (1748 seconds)
Published: Mon Oct 08 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.