Monday Monday open wide dev fans get ready to stuff your face with JavaScript CSS No module barbecue tips get workflow. It's off skill web development the hcs the karaisius the tastiest web development treats coming in hot Here is where Sarah kuda boss and Scott ill tomorrow local Tiolinsky Welcome to syntax on this Monday a ct treat we're gonna be talking about a sync local storage in the async context API in JavaScript this is a server side JavaScript thing that allows you to basically have a context amongst your entire Call stack for any given piece of information that you want to share in that regard So my name is Scott once again a developer from Denver and with me as always is Wes boss. Hey Excited to talk about it. I have done a little to talk on it a couple weeks ago, and I talked about it in my reactathon Talk which was on like next gen JavaScript frameworks I think little so just pretty cool So we're gonna kind of run through what it is and and why you might need it should we get on into it We should and I will be taking the role of somebody who has not used it I generally know what it is But I will be trying to ask you some questions So if if my questions seem dumb or if they seem like off-based try to steer me in that direction because I'm interested in this stuff And I kind of have an idea of when you would use it But I want to really get the full picture here So async local storage my understanding is that this is a new API within JavaScript inside of nodes specifically as well as what these these other runtimes other JavaScript runtimes yeah, when did this drop-in node and Is it like are all these JavaScript runtimes aligned on this so this dropped in node 13?
So it's meaning it's been around for three years already in node However, it has been gaining a little bit of momentum recently because of a few reasons one of the reasons is that this is so this is the node API Whoever there is now a proposal in TC 39 for something called the async context API, which does pretty much the exact same thing which means that People thought saw this in notes. Hey, that's actually kind of helpful wouldn't it be cool if that was just a feature We had in JavaScript in everywhere. So let's explain my inside JavaScript Yeah, exactly like I have a couple examples of like why would you ever want this in the in the browser as well? So I think local storage it's kind of like a bad name because it doesn't have anything to do with local storage It doesn't have an API like local storage really it doesn't it's not like it's not like oh, it's like it's like local storage But you can a single way to it's nothing like that.
It will allow you to access context down the call stack But so before we get into any of these things, let's understand what context is so when you have a function in JavaScript and you call that function So like let's say somebody's going to west boss calm. I'll have a route handler That's a function right and that function will get a request and then we can send a response back from it Right and then in that handler I might have a function that calls another function, right and that function will say okay Let's fetch some values from the database But that function might call another function that function might call another function right like so any function that is called within my route handler all the way down, you know function calls a function that calls another function if you ever want to Share data between all of those function calls right now the way to do it is you just pass some sort of reference or You pass something along from function to function so that anybody that needs it anywhere down the line will be able to have access to it Sound familiar? Yeah, we have a problem. Where have you seen this problem before?
Middleware so you have like in Salkits for instance the request comes in yeah, or I was gonna say react on this is something different This is that where you think in react context is that I was thinking both of those? I think you should go into both of them so in middleware typically a request comes in maybe like an off token or something you validate that User and then you pass that user information along and spell kit You know something called locals where in all of your request functions locals is just available and everything that gets saved to locals is available But it is passed through the function the other one might just be in general react context where let's say you wanted to Essentially avoid that problem of having to pass props from child to child to child to child you put something in the react context and are able to Access it outside of the the prop flow of things inside of react right exactly That's we have this problem in react and many other prop based languages where I want something to go from one level down Eight levels deep, but I don't want to have to manually pass it along every single way And we'll talk about the benefits and cons against that in just a sec as well So a sink local storage will allow you to define a store Inside of a function and then any function that is called anywhere down The the call stack or any function that is then subsequently called within that function call We'll be able to essentially just reach into the thin air and access that store and bring it down for that That makes a lot of sense because you don't have to pass along to every single function and it's really nice So what we're doing right now in a lot of use cases is we have a request object And if you want something to be able to be accessed down the line a middleware is a really good example where you might have a middleware that like Populates your user and so the request comes in you populate the user you get them from the database and then you stick the whole user on the request object and you call next or You return it and then the function that gets called next down the line We'll have access to that because it's on the request and kind of the request object or a lot of frameworks call it a context object It's kind of just a spot where you stick anything you want anybody can stick anything on there And it's really hard to type it's really hard to know what's available to yourself So the and every single function that does want to be able to access the context has to then be passed it Right? You might have context that like a top level But what happens if you want it seven levels deep in your data fetching library, right? You don't necessarily have access to it So the async local storage will allow you to define a store and access it anywhere down It's sort of like I kind of look at it as a closure variable in JavaScript If you have a declare a variable inside of a function anywhere down the level You'll be able to access a closure variable, but it doesn't work as soon as you find a function somewhere else Are you raising your hand?
I'm raising my hand. Oh, what's I would just have a quick question I want I just want to interrupt I wanted to get this before you move down from this Why would you say that most frameworks today and node aren't using async local storage for context for middleware? Yeah, that's a great question I think because it is a relatively new API and a lot of frameworks these days I specifically have been using one called hano.js a lot of these frameworks are trying to work on every single Deploy target ever so using it only using a node API is kind of a no-go for a lot of them I went into I was like okay Is this in Dino and I found literally down the thread where Ryan doll goes? This is cool.
I can see where this would be helpful But I don't want to like why are we using just a node API so that's why I'm like a So they obviously they polyfilled it and you can use it in Dino But there is a proper TC39 proposal to add this to the language So you don't you don't see this as being a part of a lot of things until the actual JavaScript Proposal gets pushed through that's a good question But so next JS has implemented it cloudflare workers has implemented it and next Yes, uses it to be able to access cookies and headers within next year So if you have an action or a server function or anything in next day Yes, and you want to be able to access the headers or the cookies you simply just import a function from next-js library called cookies You run cookies and that will give you the cookies function internally will reach out into the sky Grab the a single local storage value down and return to you all the cookies That's super nice because again You don't have to pass the headers in the cookies to every single function that needs it You can simply just access it wherever it is that you need it So I think we are starting to see this type of thing being implemented again It's only two or three years old. I guess that is kind of long But we're starting to see a lot of people find this useful because you can also I'm assuming with next-js if you have multiple middlewares You could pass data from one middleware to another because there's an API for starting it with existing data So let's go into some like actual examples of like why would you ever want to use this as well as like isn't this a bad idea for some use cases Probably the most common use case is for logging and tracing of request IDs every single time you have a request come in You can make a unique identifier for that request and use it to access it anywhere down the line So you could put a cookie in there like we've said you could use logging tracing You could you could query user preferences and just be able to get your users preferences wherever it is that you want It's pretty nice for that type of stuff I specifically when I was running all these syntax episodes through the open AI API I was firing off five at a time and I have like we have a function to Condense it we have a function to summarize it We have a conda a function to add the speaker right like there's probably 20 different functions that are running and I want to console log Running xy and z for show number 107 or show number 203 right but I don't want to pass the show number into every single one of those functions just to console log it Right, I'm not using the show number anywhere else So why do I have to pass it in just for my own logging needs? Well when you start off that initial request we put the show number in the a single local storage and then anywhere else I Work to console log I can simply just access in fact I made a custom console log function in the console log function We'll reach into link a single local storage grab the show number and then prepend the show number with the console log So my console logs are not a huge mass They're just nicely prefixed with the show number and if there's an error I can say okay Well, I know that this happened on this request or on or on this specific show parsing You might be saying well Can't you just stick a variable in memory? You know just make a variable outside your function and reference that on every single time the problem with that is if you're running two Functions at once you're on the first one you have a request ID and then the second time You have like a that might overwrite each other because if things happen out of order Then you get into real trouble because the those variables in memory are often shared and they're overriding each other This will simply just make a store when the function starts and then when it's done The whole thing is garbage collected and you don't have to worry about it anymore The API for it you can stick anything you want in it So it's not like local storage where it's a key value It could be a variable could be an object a lot of times people use sets and maps because sets and maps have nice APIs to work with them you can do whatever you want you can stick timer IDs in there Like let's say you start a timer some in one function and then you want to be able to clear the timer in another function Some I guess sometimes it makes sense just pass that idea round But if you want to be able to clear the timer you just reach into a single storage get the timer ID go ahead and clear it Promise chaining each if you use dot then and dot catch syntax instead of a sink away Sometimes it's annoying to yeah, you have to make you want like data shared between the two you have to like pass it You have to return it from the then and then you structure it in the next then or you have to like make a variable outside That's empty and then reach outside and update it right so with a single storage You could just stick each piece of data that you get into a single storage and then when it's all done You could grab it on on out from that so those are some kind of use cases.
I think in most cases User sessions user login and tracing console logs That's where 98% of this type of thing is going to lie where you need to be able to access it Some foot guns having things globally available is makes it kind of hard to test right think about if you want to test a react component But that react component assumes that it has access to data that is in context You can have the same issues here where your test runner will have to mock that context so that any functions inside of it that reach out We'll be able to access it. So it's not a very pure function When your function needs to reach into the ether and access the single storage right you can see how that could be a bit of issue Yeah, and then it could cause a memory leak as well Just like anything in JavaScript if you are referencing something and you no longer reference it JavaScript will garbage collect it However, sometimes if you reference something in JavaScript that is a variable somewhere else you would think oh yeah JavaScript will garbage collect it you can run into an issue where it's not being garbage collected and every single time you make an Object of people that increases memory usage and eventually you're gonna run out of memory and your app will fall over so Specifically this API doesn't cause memory leaks But it's just another thing to think about if you're referencing an object or value by its name You gotta think about okay. Well, maybe there's a potential memory leak there There is an exit method you can do that will explicitly clean it up if you do have that issue though That is it It's not a huge use case, but certainly will be handy I could see this being handy for events in the browser So like if you have an event that fires instead of passing the data of that event all the way down You could just stick it in sync context and be able to access that somewhere else It feels like I want to do that in my Application and stuff using the context I don't need to rewrite things But like it seems like that's like what I would want to do just throw it in a case in local storage within my my server side hook Yeah, and then be able to access it application white sounds pretty neat exactly Like it's similar to like a request object right request comes in you want to be able to access that data Then maybe an event I foresee us seeing like best practices come out of this in the next year So of like people are we used a single local storage everywhere and nothing blew up or here's a couple of use cases We did use single local storage and worked out well for us very fascinating Well cool stuff West I this is the type of stuff that I personally you know wouldn't come across it if it wasn't for somebody like you Share this awesome. All right.
Well, glad to share and we'll catch you later Peace Head on over to syntax.fm for a full archive of all of our shows and don't forget to subscribe in your podcast player Or drop a review if you like this show