JS: Advanced Fundamentals. Async Series: Callbacks (part 1)

in #javascript8 years ago

Intro

As soon as we start making useful and interesting things with JavaScript we find ourselves using more and more callbacks. Understanding them is an important step in our journey to become a great web developer.

Callback is a function that passed to another function as an argument. This function in control of executing callback, then needed. From the perspective of that function, we could think about callback as asynchronous return. Arguments that will be passed to the callback are like future return results. 

Take a look at the code below:

We defined function add as synchronous. On execution add(15, 27) JavaScript will block for a nanosecond and give us value 42. Not impressive, but good for comparison.

With the help of callback we could create a function with the same functionality, but doing it in non-blocking, asynchronous manner.

Function addAsync takes three arguments: a and b needed to make computation. callback is a function that will be called then computation is finished.

How do we call addAsync?

Output in console: addAsync result: 42

Note: addSync returns undefined, you can access result only inside anonymous function. 

Passing any function as callback.

In some cases we could chose to pass function, that already have been created:

Output in console: 42

Think about it. log is the function that lives in console object. We could pass it as any other function in JavaScript. addAsync will execute log with result argument and 42 will be logged in console.

Asynchronous.

Callbacks are instrument that we need when time element comes in our code. We are making Ajax request and we don't get a response immediately, it will come some time later. JavaScript is non blocking in nature, it doesn't wait for Ajax response, it will continue executing code. Callbacks are a way to tell JavaScript what to do then we get a response.

The canonical example of asynchronous code using build in setTimeout function:

 Output in console:

Line 19 executed right away. On line 21 we pass function named callback as the first argument, line 22 will be executed only 1000 ms later. JavaSctipt will not wait for setTimeout to finish, it goes forward to line 25.

Reading files from disk

Here is a more useful example, using callback in Node JS to read file from the disk. 

Output:

At this point this should be familiar to you. It looks like a silly addAsync function, we looked earlier. 

Function readFile takes three arguments: path to file, options and callback. Then readFile finish its job, it will give us result by executing our callback with two arguments. We should know in advance 'signature' of callback. In this example the first argument by Node convection is error and second is data from file. Knowing that, we are defining anonymous function with specified parameters and passing it to readFile.

That is next?

First is the first part of the series about asynchronous tools in JavaScript. Thing will get more interesting soon. Next time we will build fakeAjax function that will be useful for our subsequent exercises with Callbacks, Thunks, Promises, Observables and Generators.

We have a lot to cover. See you soon!

Sort:  

Great post and information!

Nice post, thanks!
It would be great if you add a list of situations when we should use async.

Good question!
If you using libraries or native functions with async API than you have no choice, but use it in asynchronous manner.
Native setTimeout and setInterval could be used only by providing callback.
Making network request with Ajax library always asynchronous. You never know than you will get response. It is possible to make synchronous request, but it will freeze browser for user, so it is bad practice.
Read data from disk or database is slow, better to do it async style with Node JS.
All user interactions are asynchronous in nature. You never know then he presses a button.

So all heavy functions should be async, like

  • heavy calculations,
  • input/output operations,
  • system calls,
  • database calls,
  • updates/analyse HTML tree,
  • graphics (may be)?
    ...

Hmm... if we create a lot of async functions, processor will try to run em all at once? It could be bad for slow computers... But some browsers are run in a single process (old firefox, for example).
Today we have users with very fast computers and usually slow smartphones...

Sorry for late response (sleep, job).
JavaScript is single threaded, there is no way in the language to manage threads. You can spinn up a lot of JS/Node processes though, but as a programmer you can manage only one.

Heavy calculations and graphics will be syncronous. You can simulate heavy calculation by running for in loop billion times. If you do it in browser, you will find, that it freezes your window for a couple of seconds. I'll try to illustrate it in later post. Good call!

Modern browsers spinn up multiple instanses for faster perfomanse. You can do it yourself with Node. But this instances have limited abylity to communicate to each other. Script you write will only be executed in one thread.

Threads is an instrument to solve concurrency problem in programming, JavaScript solved concurrency by build in async. There mechanism under the hood called Event Loop, it some sort of the queue, which Javascript uses to know when to run your callback.

Thank you! It was very informative,
I am programming usually on perl and my knowledge about javascript is tiny, only base syntax and jquery.

Callbacks in comedy are a completely different thing. I wish there was a programming function for THAT. :)