Understand Callbacks in Node.js

Will Button
InstructorWill Button

Share this video with your friends

Send Tweet
Published 7 years ago
Updated 3 years ago

In this lesson you will learn what callbacks are, how to use them and why we use them in our Node applications. We start with a simple javascript function and build a second function that uses it as a callback to understand the basic operation of a callback. From there, we create a few more functions that help illustrate how using callbacks can help us keep our code legible and organized as well as allowing us to use generic functions that can bring in extra functionality when needed via the callback.

[00:00] Today, we're going to talk about callbacks, and we're going to remove all the mystery that surrounds them by learning about what they are and why we use them in Node.

[00:09] To get started, we're going to use the Node Ripple interface. We get into that by typing the node command with no additional parameters.

[00:17] Now, we're going to start by typing just a simple JavaScript function, and we're going to call it "welcome message." It's not going to take any parameters. All it's going to do is just write out to the console, "Welcome to the Great Underground Empire." We can execute that just by calling it directly, and it writes out to the console as expected.

[00:50] Now, let's create another function. We're going to call this one start. It's going to accept a parameter that we're going to name callback. Inside this function, we're just going to execute the callback that's passed in as a parameter.

[01:10] Now to watch this work, we're just going to call our start function and the parameter that we passed is the function we defined previously. When you watch this run, you can see that what happened was it wrote to the console, "Welcome to the Great Underground Empire," just like it did when we called the welcome message directly.

[01:36] The reason that worked is because the parameter that we passed in was our callback. That's the great mystery of callbacks. All that a callback is is a parameter to a function that happens to be a function itself. When we passed in that parameter, and then executed that as a function, it ran, because it was a function.

[02:02] The big question is, "Why would you do that?" The reason is it's how Node gets it's asynchronous operation, because when this executes, regardless of the status of that callback, the start function is going to return, which means Node is available to take another request.

[02:20] It might be a little hard to imagine since the function that we passed to start just wrote out to the console, but if you imagine a different function that was parsing a large file or making an http request that was not responding quickly, you could see where that would cause your start process to hang and be nonresponsive while it was waiting for that to return if you didn't use callbacks.

[02:51] In the end, that just means that people would be trying to hit your app, and they wouldn't be able to get through, because your process is hanging out waiting for something to finish. Callbacks are the key to eliminating that.

[03:02] Let's create a couple of other functions here that are going to illustrate some of the other benefits of callbacks. We're going to create one called look. This function is going to take a parameter called "dir." We're just going to say, if dir is equal to the string west, then, we want it to write out to the console, "There is a small mailbox here."

[03:32] Then we'll say, if dir is equal to the string east, write out to the console, "You are standing next to a white house." That's going to do it for our look function. Let's create one more called "walk." Just like look, it's going to take dir as a parameter. You'll see a similar pattern here.

[04:05] If dir is equal to the string west, we want to write out to the console, "It is very dark. You're likely to be eaten by a grue." Then we'll say, if dir is equal to the string southconsole.log, "You're standing on the edge of a deep chasm."

[04:42] Now, we've got two different functions here, and they serve to illustrate one of the other features of callbacks. That's the ability to group our code according to what it's doing. We created a function called "look," and inside of there, we have the code that relates to the different operations that can happen within our look function.

[05:03] Then, we have a separate one called walk that relates to the walk operation. It makes the code easier to maintain, easier to read. Then, the last thing that callbacks give us the ability to do is reuse generic functions.

[05:21] If we create a function called "get input," and it's going to accept param and cb as parameters, all it's going to do is execute cb as a callback passing in the parameter. To see that in operation, we can say, "Get input," pass in the string west, and call the function look.

[05:56] You can see it says, "There's a small mailbox here," because what we did was we passed in our look function as the callback. It gets executed carrying along this parameter of west. Inside the look function, if the string is equal to west, then, it's told to write out to the console, "There's a small mailbox here." That's exactly what it did.

[06:23] We can do get input east with our look function, and you see that we're standing next to a white house. Let's go ahead and finish this thing out by supplying west as our parameter and walk as our callback.

[06:45] You see if we go that way it's very dark. We're likely to be eaten by a grue, instead, we're going to go south with our walk callback. We find ourselves standing on the edge of a deep chasm as this lesson comes to an end.

Tomasz
Tomasz
~ 6 years ago

It is understandable why callbacks are introduced, but with native promise support (from version 4, I believe - we have version 7 now) callback's approach should be marginalized.

Will Button
Will Buttoninstructor
~ 6 years ago

Yup, agreed. This lesson was recorded when 0.12 was the latest and greatest. Callbacks are still a large part of the existing ecosystem, so it's good knowledge for those new to node.js. Stay tuned for some new lessons on Promises in node.js in the next couple of weeks! Thanks for your feedback!

Logan May
Logan May
~ 5 years ago

I'm new to node.js and a relatively new developer in general, so I have a fairly basic question. If welcomeMsg() prints the text and then returns undefined (which we see in our console,) and start calls welcomeMsg, then why doesn't calling start(welcomeMsg) print undefined twice? I thought it would - once for the call to start, which returns undefined, and once for the call to welcomeMsg, which does, as well.

Will Button
Will Buttoninstructor
~ 5 years ago

Great question Logan. When using the console, our interaction with Node is done with a REPL, which stands for Read - Evaluate - Print - Loop. The "Print" portion is the key here. In the REPL interface, it prints the output of whatever you give it and in cases where there is no output, the output is undefined. In the second example, welcomeMsg is called from the start function. The start function doesn't get a return value back, and isn't expecting one because it just executes the function. Had we done something different like

var foo = callback;
console.log(foo);

it would have printed undefined as you were expecting. Another way of stating that might be to say that the REPL interface is tied to the start function. So, it Reads the start function, Evaluates it (or executes it), Prints whatever it got back, then Loops back to the cursor waiting for you to tell it what to do next. Everything that happened within the start function was done inside of Node, and only its return values were available to the REPL. Hope that makes sense, if not- please let me know!

Kalpana
Kalpana
~ 4 years ago

2:20 transcript - You say that the start function calls the callback and returns immediately, without "waiting" for the status of the callback.. so node is available for the next request, ... but then you proceed to say that if the callback was not merely writing to the console in this example, and was a function that parsed a large file, then start function would hang indefinitely. Does this mean if welcomeMsg() function was parsing a large file etc. start would wait on it ? I understand it does not based on the lesson, just wanted to clarify.

Patrick
Patrick
~ 4 years ago

2:20 transcript - You say that the start function calls the callback and returns immediately, without "waiting" for the status of the callback.. so node is available for the next request, ... but then you proceed to say that if the callback was not merely writing to the console in this example, and was a function that parsed a large file, then start function would hang indefinitely. Does this mean if welcomeMsg() function was parsing a large file etc. start would wait on it ? I understand it does not based on the lesson, just wanted to clarify.

Kalpana The video seems to imply that Node is non-blocking in general. I am new to Node but that didn't seem correct to me, so I executed callback functions which were long-running but didn't involve I/O. The instructions ran sequentially as expected.

The article below provides clarity.

https://greenash.net.au/thoughts/2012/11/nodejs-itself-is-blocking-only-its-io-is-non-blocking/

J. Matthew
J. Matthew
~ 3 years ago

Shout-out to Zork.