Before we dive into asynchronous programming, let's take a look at one important point related to code execution. Take a look at this example:
const data = [16, 64, 4];
const data2 = data.map(Math.sqrt); // [4, 8, 2]
const predicate = (v) => v > 2;
const data3 = data2.filter(predicate); // [4, 8]
Each line in the code above is executed only when the previous line is executed. In programming, this sequential execution of code (instructions) is called synchronous. And the execution of each particular line can be as complex as you like.
If you look at the second line, you can see that the map()
method is called, which internally calls Math.sqrt()
. In real-world applications, the depth of nesting with functions can be simply enormous, reaching hundreds of levels. During code execution, this kind of failure creates a call stack. Why a stack? Because that's how the code execution process works. Each internal call adds the current function inside the stack, and that keeps happening until we reach the deepest possible function. Then, when it comes to returning, the stack comes undone; functions are retrieved from it one by one (in reverse order) and continue their execution from the place where the internal function returned the result.
Suppose we have a chain of functions one() calls two(), which calls three(), which calls four():
const four = () => console.log('END!');
const three = () => four();
const two = () => three();
const one = () => two();
one(); // Running
Then the code execution process will look like this:
one
=> two
=> three
=> four
=> three
=> two
one
I.e., first it dives down to the nested call, then it climbs up to the first function in the call stack.
We, as developers, see call stacks every day in the error output. Backtrace is nothing more than a call stack written in reverse order. To demonstrate this, I made a mistake in the third line of our code:
const data = [16, 64, 4];
const data2 = data.map(Math.sqrt); // [4, 8, 2]
const predicate = (v) => unknown > 2;
const data3 = data2.filter(predicate); // ReferenceError
Running (the code is in the index.js) and output:
node index.js
index.js:3
const predicate = (v) => unknown > 2;
^
ReferenceError: unknown is not defined
at predicate (index.js:3:32)
at Array.filter (<anonymous>)
at Object.<anonymous> (index.js:4:21)
It is important to understand that the call stack only grows when calls go further down. This can be seen from the output: the backtrace doesn't include the first and second lines, it describes the sequence starting from the filter call and goes on.
The exception mechanism in js, as in other languages, relies entirely on the presence of a call stack. What's more, it's designed to make it easy to undo this stack. Any exception that arises goes up the call stack until it encounters a try/catch construct or until the call stack runs out.
const data = [16, 64, 4];
const data2 = data.map(Math.sqrt); // [4, 8, 2]
const predicate = (v) => unknown > 2;
try {
const data3 = data2.filter(predicate); // ReferenceError
} catch (e) {
console.log('Catch it');
console.log(e.stack);
}
Even though the declaration of the predicate()
function containing the error is outside the try/catch block, it will still catch the error inside that function, since predicate()
is called internally in the chain.
node index.js
Catch it
ReferenceError: unknown is not defined
at predicate (index.js:3:32)
at Array.filter (<anonymous>)
There are special tools that allow you to visualize the call stack. Usually, they're used during profiling — the process of finding bottlenecks to speed up an application.
But everything changes when it comes to asynchronous code. More in the next lesson.
The Hexlet support team or other students will answer you.
A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.
Programming courses for beginners and experienced developers. Start training for free
Our graduates work in companies:
From a novice to a developer. Get a job or your money back!
Sign up or sign in
Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.