“Rethinking Asynchronous JavaScript” by Kyle Simpson
This past week, I began the course “Rethinking Asynchronous JavaScript” given by Kyle Simpson, head of curriculum at MakerSquare and author of You Don’t Know JS series. Unlike other workshops that focus on how to use a specific technology, Simpson works to build up our conceptual understanding of how JavaScript works before giving us example problems to solve. In the case of this course, he explains several patterns for dealing with asynchronous JavaScript calls, beginning with what is asynchronous versus parallel processing - the two are often conflated.
As he explains, parallel processing is actually the opposite of non-parallel processing. Giving the example of a rollercoaster ride, non-parallel processing is where a single person gets on a ride at once. With parallel processing, 30 people get on the same ride and experience it at the same time. Asynchronous processing is different from both of these. In asynchronous processing, two or more macro-level processes are broken down into micro-level tasks. These micro-level tasks are interwoven and happen at different times, but overall it takes the same amount of time to process both macro-tasks.
In asynchronous processing, micro-level steps happen not in order, but out of order, and the macro-tasks are said to happen concurrently. “Asynchronous patterns”, he tells us, “is a way to manage concurrency patterns,” which can become very complex.
One way to handle concurrency and asynchronous tasks is to use callbacks, but this produces some problems. One familiar problem is what is called callback-hell or the pyramid of doom, but Simpson explains that the real problem with these nested calls is not what they look like, but that it makes our code difficult for coders to reason about and to follow. The main issue with using callbacks to handle concurrency is what is called the inversion of control, which is when we hand over control of one part of our program over to another part of our program hat we don’t control. This exposes a trust point that creates bugs that can emerge in unexpected and surprising ways.
Our brains, Simpson explains, are single threaded at even the highest levels - as we have come to learn, there is no such things as multitasking. Wherever our brain diverges from how JS works, that is where bugs happen. If you write your code more like your brain thinks, there is less divergence and fewer bugs; if you can learn and use patterns that work like your brain thinks, that is the best approach. So we need better patterns with which to handle concurrency.
The rest of the course covers several different solutions to concurrency, and a single problem example is solved in these multiple ways to expose the particular strengths and weaknesses of each approach.
In what follows, Simpson explains a very old pattern that has been around since the 60’s, called thunks, a pattern that underlies modern Promises. Now, Promises is a solution not only to concurrency and managing state in asynchronous Javascript programing, but also the trust point issue. But Promises exposes another set of problems, and Promises is best paired with generators. This will the subject of the rest of the course, which I will cover in a subsequent blog post.











