This was the week we started on our two week API Express project. The project is based on the idea of a music library, you can have a look at my project progress here. We also learned a lot of new concepts, some of which I have tried to detail in this blog post. It's worth mentioning that my cohort works through the projects at slightly different speeds, helping each other, sharing mile stones and questions on Slack, and supporting each other. It definitely helps to have people to share with!
So, what did week 13 look like?
Blocking & the stack
When a webapp runs and the browser appears to freeze because an intensive chunk of code is being processed, this is called blocking. All code is blocking in JavaScript, because JavaScript runs single threaded, but some code blocks longer than others. It's important to pay attention to the order of your code and how it's written, to avoid anything that can block the thread (e.g. infinite loops). Any “slow-running” code will block the execution of subsequent statements.
All function calls are stacked on top of each other, JavaScript runtime pushes a new entry to the top of the stack when a call is made and it removes from the stack when a function finishes running and returns.
When you get a JavaScript error, you get a stack trace. Errors are a snapshot of the call stack when things go wrong! It's important to pay attention to file names and line numbers and see the difference between library code (node_modules) and your application code by investigating file paths
Asynchronicity in JavaScript
JavaScript is, generally, single threaded and synchronous (one single task happens after another). This can be quite frustrating (think about when you see the rainbow beachball on your Mac) as everything else has to wait for for one function to finish and return. The basis of asynchronous programming is letting one task work away, while other things also happen. Now that many computers have multiple cores, they can do multiple tasks at once. Operations like making a network request or querying a database can be time-consuming, but JavaScript allows you to execute other tasks while waiting for their completion.
Asynchronous code is code which runs at a later time, implemented as callback functions. Callback functions are functions that run after a bit of code has completed or waited for something else. Some examples of asynchronous JavaScript methods are:
- setInterval() and setTimeout().
- HTTP calls.
- Reading/Writing from the filesystem (in Nodejs).
Callback Queue & Event Loop
JavaScript uses an event-loop which allows it to efficiently execute other tasks while it awaits the completion of these asynchronous actions.
If the call stack is not empty, any callback functions called during that time will be added to the callback queue. This queue is where code is kept until it is ready to resolve. The event loop periodically checks if the callback stack is empty and pushes the first item on the queue on to the stack!
To try and understand JavaScript's call stack, the resources here will go a long way; there is a video & an interactive page. Also this dev.to article has a fab visualised loop.
Using callbacks to control async code can quickly become nested. This makes it hard to follow what callback function is happening. This infamous callback hell is caused by trying to write the code in a top to bottom manner. The way to solve this is by using a solution from ES6 - Promises.
Though this is not a full escape from callbacks, a promise object represents the eventual completion of an async operation, and its resulting value or error. Promises makes asynchronous code much more concise, readable and easy to manage. I'm still very much learning about Promises so I have linked a few resources here which have helped me: W3Schools and web.dev.
On top of JavaScript promises, there is also now new syntax (from ES8) for handling asynchronous actions async...await
. Though this doesn't bring new functionality to JavaScript, I'm mentioning it in case you come across it in your other reading. There is some documentation here.
Here's to week 14 of bootcamp!
My Key Take Aways
This is hard - Everyone I've mentioned async JavaScript to, has pulled a bit of a face and mentioned how advanced and difficult it is. I'm definitely going to be learning this for a while!
Take your time - If you can learn one new thing a day, that is improvement. Even if it just the existence of a new function, or new term. Remember, you can always read more about it and add to that learning tomorrow.
Lots of resources - Because async JavaScript, callback queue and event loop are difficult, luckily there's a lot of great resources out there. People are writing about it, demo-ing, doing videos so if you're still not getting it, do persevere because there is someone out there explaining it in a way which will make it all click into place. That wonderful light bulb moment is out there, I promise.