Asynchronous JavaScript using Callbacks

I recently struggled when faced with a problem of using callbacks to handle the asynchronous flow of multiple API calls.

So I figured I’d do a deep dive into callbacks to refresh and solidify my knowledge.  After all, if you want to truly understand something, teach it to someone else!

Functions as First Class Objects

Before we start talking about callbacks, we must first know that JavaScript functions are first-class objects.

Which means what?  And why is that important to a discussion about callbacks?

Being a first-class object in JavaScript means that functions can have properties and methods just like any other object.  Consider this:

It also means that functions can be assigned to a variable.

More importantly for our discussion on callbacks, however, is that because functions are first-class objects, they can be passed to (and returned from) other functions.

This last point, passing functions as arguments to other functions, is the foundation of callbacks.

A callback is simply a function that is passed to another function as an argument, that can then be used (executed) inside that other function.

The previous example used a named function (answer) as the callback. You can (and probably have) also use anonymous functions as callbacks.  This is common when passing callbacks to the native prototype methods for arrays, objects and strings.

Consider the following:

Here we used an anonymous arrow function as our callback to output twice the value of each element.

Now that we know what callbacks are, let’s talk about their use in asynchronous JavaScript.

Understanding ASYNCHRONY

Image of the Police Album - Synchronicity

No, this isn’t what we’re talking about, but the word ‘asynchony’ makes me think of this album…..  Yeah, I know, I’m old…

Before we start talking about controlling asynchronous flow we must first understand the nature of the JavaScript event loop and the fact that it is single threaded. Digging deep into the JavaScript engine is beyond the scope of this post, but understanding the single threaded nature of the event loop is critical to understanding why we need asynchronous code.

For now, think of the event loop as a queue (first in, first out) that executes snippets of your JS code one by one and in the order they were placed in the queue.

Now think of an Ajax request that we might use to get some data from an API.  That Ajax request is costly (in time).  If we place it in the event loop and run it synchronously it will block everything that comes after it while it waits for a response. This affects performance and causes people to leave your site!

In his You Don’t Know JS series, Kyle Simpson describes asynchrony as the difference between now and later, as opposed to parallel, which describes two processes that are executed independent of each other (but possibly at the same time).

This now and later concept is where callback functions come in.  Rather than running that Ajax request from start to finish, blocking all other code execution while we wait, we pass it a callback.

In this scenario, the JS engine can make the Ajax call (now), continue with the event loop, and once the Ajax call returns (later) pass the callback, along with any data it needs from the response, back into the event loop.

Async in action

Let use an example to show what we’re talking about.  For the remaining examples, I’m going to use setTimeout() to simulate async functions, but you can think of it as time spent making an Ajax request.

This example shows asynchronous control of the event loop. Let’s dig deeper in case this isn’t clear.

We’ve defined three functions first, second and delay.

first and second merely log “first” and “second” to the console so we can tell when they’re executed.

delay takes a callback, which it passes to setTimeout(). setTimeout() sets a timer, then calls the function it was passed – in this case, it will call callback after 500 milliseconds.

After the three function definitions, we call delay(first), which puts the function delay() in our event loop.  Upon execution, delay sets a timer for 500 ms, after which, it will call its callback (in this case first()).

Because the timer in setTimeout() is non-blocking, or asynchronous, the event loop is now free to move on to the next snippet of JS, which is our function call to second().

When second is executed, it logs “second” to the console, which is why we see “second” logged to the console before we see “first”, even though delay(first) was called before second().

And finally, after the 500 ms timer elapses, first() is placed in our event loop and executed, which is when “first” shows up in our console.

I’m hoping the example above was simple enough that you could figure it out on your own, otherwise, maybe my long winded explanation helped.

Fun with callbacks and closure

OK, now that we’re pros with callbacks, lets have a little fun with them!

We’re going to use callbacks and closure to set up a four lane race. Granted, it’s only a race in the sense that we’re randomizing the setTimout() time, but it’s fun nonetheless…

Hopefully, the comments in the code clear up how the “race” is being run. If you have any questions, feel free to leave them below.

-Jeremy

 

 

 

 

 

 

Intro to Scope – An Exercise in Rubber Ducking

As I stated previously, I’ll be writing a series of posts attempting to explain, or rubber duck, some of the more difficult topics in the You Don’t Know JS (YDKJS) series by Kyle Simpson.

Before you start screaming at me that Kyle Simpson has forgotten more about JavaScript than I ever knew, to which I would wholeheartedly agree, please read the following disclaimer…

Disclaimer:

I have great respect for Kyle Simpson, his method for teaching and the YDKJS series.  This series of posts were not endorsed by Simpson and are merely an attempt to supplement his books.  This project is being created for the sole purpose of helping to solidify these concepts in both your mind and mine.  If you are learning to code in JavaScript, I highly encourage you to read the YDKJS series.

What is Scope?

Variables are extremely important to computer programming.  They allow us to write complex and dynamic programs.

But how and where should we create variables? How and where do we store them?  And, maybe most importantly, how and from what part of the program are we able to access a particular variable?

Each language has very specific rules for these questions.  These rules can be thought of as Scope.  Here we’ll introduce the rules of scope specific to JavaScript.

Given that scope is a fairly broad topic, with many different aspects to cover, I think it best to break this into multiple blog posts.  The goal here will be to introduce the topic of scope and provide a foundation that we can build upon in later discussions.

What we cover here can be found in far greater depth in the 2nd YDKJS book – “Scope and Closures”.

Let’s begin by taking a step back…

JavaScript is a Compiled Language (surprise!!)

For those who have worked with more traditionally compiled languages like C++ or Java, it may come as a bit of a surprise that JavaScript is actually compiled before it runs.  This misunderstanding is likely because, unlike many other languages,  JavaScript is compiled just before run time rather than in an entirely different build step.

Right now you may be asking yourself why this is relevant to a discussion on Scope…  That’s a great question, let me try to explain.

Simpson describes that, at a very high level, the 3 basic steps in compilation are 1) tokenizing/lexing, 2) parsing and 3) code-generation.

The tokenizing or lexing step breaks up strings of characters in your code into chunks (tokens) that are easier to understand.  Next, the parsing step takes all these tokens and forms a tree of nested elements called an Abstract Syntax Tree. This tree represents the grammatical structure of the program.  It is from this AST that code is generated in step 3.

Still not clear on how this relates to scope, right?

To clear this up, you must understand that JavaScript employs lexical scoping rather than dynamic scoping.

This means that the scoping for a program is determined at the time of lexing, based on where the variables fall within the blocks of scope. Therefore the author is able to control the scope at the time he is writing the program without worrying that the scopes will change at run time.

This is a key concept in understanding the behavior of scope.  For more detail, please read the first 2 chapters in  “Scope and Closures”.

As with most rules, there are exceptions….  Simpson discusses several ways to change lexical scoping at run time.  This can be accomplished using eval() and with(), both of which he frowns upon using.  I don’t plan on going over these here, but you can be read about them in Ch. 2 .

General rules and behavior of scope in JavaScript

Generally speaking, (and again, there are several exceptions to this rule, which we will likely cover in later posts) JavaScript derives its scope from functions.

What does this mean?

You can think of scope as a series of boxes contained within each other. These boxes contain the functions and variables that are declared within that function.  This structure enables control over how one block of scope is allowed to access another.

In JavaScript, there is a scope (or box) that contains the entire program, called global scope.  Each time you create a new function, a new scope box is created.  This new scope will contain any new variables or function declared within (including any parameters declared in the function definition).

And so on, and so on, as functions continue to be nested within other functions…

Mentally, you can picture scope as something like this:

A group of nested boxes meant to depict the concept of scope.
The numbers are included only for reference and should not be used to infer relationships between blocks.

When you reference a variable within a JS function, the current scope will be searched.  If the variable is found, great, that’s what will be used.  If it isn’t found, the JavaScript engine will continue to search the scope boxes incrementally outward.  The first match it comes across will be used.

Let’s use the model depicted above…  Let’s say the function for scope #5 referenced a variable called ‘foobar’.  If ‘foobar’ was not found in scope #5, the JS engine would then search scope #3.  If not found in #3, it would search #2, then #1.  Scopes #6 and #4 would not be searched.

What happens if the JS engine reaches the global scope and is unsuccessful in finding ‘foobar’?  The answer to that depends on what you are trying to do with the variable.

LHS vs RHS References

Simpson describes two scenarios for referencing a variable.  He calls them LHS (Left hand side) or RHS (Right hand side) references and they are handled differently in the case of an unsuccessful lookup.

While LHS and RHS refer to which side of the assignment operator (=) the variable is found, this shouldn’t be taken literally, as there are multiple ways to assign a value to a variable.

Rather, think of the difference as such…  LHS is a lookup where we are trying to assign a new value to the variable, whereas RHS is merely looking up the value of the variable to use within your function.

Let’s look at an example:

First, let’s go through this code, find the variables and decide in which scope they reside. There are 2 distinct blocks of scope here.  The global scope and the scope inside the addOne function.

There’s only 1 variable in the global scope and it’s the function addOne. The scope nested inside the addOne function contains 2 variables, sum and a.

Now, where and how are these variables referenced?

There are 2 references to each variable in the addOne function.

Line 1 contains an LHS lookup for a.  It’s LHS because we are assigning the value of 9 to the variable a when the function is called.  Then there is an RHS lookup of a in line 2, as we are only looking up the value of a to use in a+1 (the value of a will not change as a result of this reference).

There’s also one of each type of reference to sum.  The LHS reference to sum is on line 2, where we are assigning the value derived from a+1 to sum.  The RHS reference to sum occurs on line 3, where we lookup and log its value.

The last lookup is on line 6 where we perform an RHS lookup to addOne by invoking the function.

Note: Originally, I mistakenly assumed there was also an LHS reference to addOne on line 1 when we declared the function.  Simpson states in ch. 1, however, that due to the way the compiler handles function declarations, it would be wrong to think of them as LHS references.  Please see YDKJS for further clarification.

RHS… LHS…  Why does it matter?

You may be saying to yourself RHS… LHS… ABC…  XYZ…  Who gives a $*&# as long as I have access to my variable…  The distinction comes when the engine is unsuccessful in finding the variable for which it’s looking.  Knowing the difference now might save you a loooong time in debugging later.

So, what is the difference between an unsuccessful RHS vs LHS lookup? The difference lies in how the engine handles them.

When the engine is unsuccessful in an RHS lookup it throws a ReferenceError.  If the engine does find the variable, but the program is trying to do something with the variable that doesn’t make sense (i.e. invoke as a function a non-function variable), the engine will throw a TypeError.

LHS lookups, on the other hand, are a different story.  If the engine is unsuccessful in an LHS lookup, it simply creates the new variable in the global scope and hands it back to the engine.  As you can imagine, this can lead to all kinds of headaches.

You can prevent this by running in strict mode with "use strict";.  An unsuccessful LHS lookup in strict mode will result in a ReferenceError, similar to that of an unsuccessful RHS lookup.

Let’s look at some examples…

Let’s say we make a typo on line 3 when we are logging sum and mistakenly write sums.

Getting a ReferenceError: sums is not defined tells us that we tried to reference a variable named sums that we failed to declare in a relevant scope.

Another example… Let’s say we try to invoke something that isn’t a function.

Again, the error we get tells us exactly what we should be looking to fix.

Now for an LHS example.   Consider the following:

You can see here that 10 is logged to the console.  Even though we didn’t declare sum as a variable, the engine went ahead and created it for us and the function completed without an error.

What about strict mode?

We can see here that strict mode prohibited the creation of an undeclared LHS reference.

As you can see, knowing the rules of scope and how errors are thrown can significantly cut down your troubleshooting time.

 

I am the scope master!!

Ok, that was a lot to take in, but seemed pretty straightforward.  Is there more to learn on scope or am I now a scope master?

Settle down Yoda…  There are some more advanced topics on scope that I plan to cover in a future post, such as function expressions, IIFEs, hoisting, block scope and the use of let and const.

There are also scope closures to discuss…  I’m not exactly looking forward to writing that one, as closures can be pretty damn confusing.  But, hey, that’s what these rubber ducking exercises are all about, right?

I hope you found this helpful, feel free to leave your comments below.

That’s it for now, I hope this helped straighten out the code…

-Jeremy

 

Rubber Ducking and ‘You Don’t Know JS’

I’ve recently been working my way through the You Don’t Know JS books by Kyle Simpson. If you are learning JavaScript and haven’t taken a look at these books, uhhh, what are you waiting for??

“JavaScript sucks man….”

There are a lot of arguments out there as to why JavaScript is such a shitty programming language. Accompanying each of these arguments are books and blogs by authors that try to teach JavaScript in spite of it’s shittiness!!

“Uhhh, no, you just don’t get it…”

Kyle Simpson takes the opposite approach… As you can see in the Preface of his YDKJS series, his opinion is that JavaScript is a deep and rich language that few developers take the time to know properly. His argument is that when faced with an obstacle, many JS developers blame the language rather than their lack of understanding.

Now that sounds like someone I want to learn from! Taking this approach establishes a level of accountability and responsibility to one’s craft.

So when other authors are saying ‘JS is a shitty language, here’s how to get around it’s shittiness’, Kyle Simpson is saying ‘JS is a deep and powerful language, here’s how to embrace it and have it work for you.’

I’ve read three of the six YDKJS books completely and skimmed through the other three. There are some really difficult concepts covered that take a couple times reading through to fully grasp. Concepts like closures, modules, ‘this’, prototypes and async to name a few..

What’s the point of this post??

I plan on writing a series of blog posts that work through these concepts and explain them at a basic level. Do I think I can explain these better than the author? Absolutely not, so I encourage you to read the books (in addition to my blog, of course).

I am, however, doing this for two reasons.

First, obviously I’m far closer to a beginner than Kyle Simpson, which, believe it or not, can have it’s advantages when trying to explain complex concepts. It’s possible that I can word these concepts in a way that might be more relatable to someone just starting out. (I’m not saying it’s going to happen, just that it’s possible)

Second, it’s an exercise in rubber ducking.

rubberduck

And what the hell is Rubber Ducking??

If you haven’t heard the term, rubber ducking is a technique by which you try to understand something by explaining it to a rubber duck.

The theory is, in order to teach it to someone who has no previous understanding (i.e. the duck), you must completely understand the concept yourself! (if you haven’t noticed, I do a lot of rubber ducking here at Crooked Code)

So rather than just read through these books for a second time, I’m going to work through them and try to teach these concepts so they might be understood by a beginner.

Even if nobody reads or visits these posts, I will have gained a better grasp of the difficult parts of JavaScript by teaching them…

More rubber ducking posts to come, I hope you enjoy and get something out of them.  That’s it for now…

-Jeremy