NodeJS Basics

Mahmood Nalim
12 min readNov 1, 2023

What is the Event Loop?

The event loop is what allows Node.js to perform non-blocking I/O operations.(despite the fact that JavaScript is single-threaded)

The event loop is a fundamental concept in Node.js that allows for asynchronous programming. It is a continuously running process that monitors the call stack and the callback queue, and executes tasks when the call stack is empty.

Features of Event Loop:

  • An event loop is an endless loop, which waits for tasks, executes them, and then sleeps until it receives more tasks.
  • The event loop executes tasks from the event queue only when the call stack is empty i.e. there is no ongoing task.
  • The event loop allows us to use callbacks and promises.
  • The event loop executes the tasks starting from the oldest first.
  • When a function is called, it is added to the top of the call stack, and when it returns, it is removed from the stack.

This is called non-blocking behaviour where all the synchronous functions are processed and executed first and asynchronous functions are processed in the background while waiting their turn to get executed.

All the asynchronous functions get processed and their callbacks are stored in the callback queue.

Note: Asynchronous functions cannot run inside a callback stack until it gets emptied(pop).That means that after main() is removed from call stack, only then can all asynchronous functions start executing.

Differences between Node.js and the Browser

In the browser, most of the time what you are doing is interacting with the DOM, or other Web Platform APIs like Cookies. Those do not exist in Node.js,

And in the browser, we don’t have all the nice APIs that Node.js provides through its modules, like the filesystem access functionality.

Another big difference is that in Node.js you control the environment.

Another difference is that Node.js supports both the CommonJS and ES module systems (since Node.js v12), while in the browser we are starting to see the ES Modules standard being implemented.

Getting started with Node.js

Node.js. is a run-time environment.

The Node.js Javascript code uses the Google V8 engine.

Node.js, the difference between development and production

Node.js assumes it’s always running in a development environment.

You can signal Node.js that you are running in production by setting the NODE_ENV=production environment variable.

const env = process.env;
env.NODE_ENV === "production"

Node.js with TypeScript

Basically, it’s a superset of JavaScript that adds new capabilities to the language.

The most notable addition is static type definitions, something that is not present in plain JavaScript.

Thanks to types, it’s possible, for example, to declare ,

what kind of arguments we are expecting

what is returned exactly in our functions

what’s the exact shape of the object that we are creating.

how do we run it?

First thing to do is to install TypeScript in our project:

npm i -D typescript

Now we can compile it to JavaScript using tsc command in the terminal. Let's do it!

npx tsc example.ts

npx here stands for Node Package Execute. This tool allows us to run TypeScript’s compiler without installing it globally.

tsc is the TypeScript compiler which will take our TypeScript code and compile it to JavaScript. This command will result in a new file named example.js that we can run using Node.js.

TypeScript offers a whole lot of other great mechanisms like interfaces, classes, utility types and so on.

State management in NodeJs

Functions may or may not be state dependent. State dependency arises when the input or other variable of a function relies on an outside function.

In this way there are two primary strategies for state management:

  1. passing in variables directly to a function, and
  2. acquiring a variable value from a cache, session, file, database, network, or other outside source.

You will be able to perform almost all of your operations with the following 3 patterns:

  1. In series: functions will be executed in a strict sequential order, this one is most similar to for loops.
  2. Full parallel: when ordering is not an issue, such as emailing a list of 1,000,000 email recipients.
  3. Limited parallel: parallel with limit, such as successfully emailing 1,000,000 recipients from a list of 10E7 users.

Overview of Blocking vs Non-Blocking

All of the I/O methods in the Node.js standard library provide asynchronous versions, which are non-blocking, and accept callback functions. Some methods also have blocking counterparts, which have names that end with Sync.

const fs = require('fs');
const data = fs.readFileSync('/file.md'); // blocks here until file is read
console.log(data);
moreWork(); // will run after console.log
const fs = require('fs');
fs.readFile('/file.md', (err, data) => {
if (err) throw err;
console.log(data);
});
moreWork(); // will run before console.log

JavaScript is synchronous by default and is single threaded. This means that code cannot create new threads and run in parallel. This is why Callback functions are introduced.

Discover JavaScript Timers

setTimeout()

When writing JavaScript code, you might want to delay the execution of a function.You specify a callback function to execute later

Zero delay

If you specify the timeout delay to 0, the callback function will be executed as soon as possible, but after the current function execution:

setTimeout(() => {
console.log('after ');
}, 0);
console.log(' before ');
//output
//before
//after

This is especially useful to avoid blocking the CPU on intensive tasks and let other functions be executed while performing a heavy calculation, by queuing functions in the scheduler.

setInterval()

setInterval is a function similar to setTimeout, with a difference: instead of running the callback function once, it will run it forever, at the specific time interval you specify (in milliseconds):

const interval = setInterval(() => {
if (App.somethingIWait === 'arrived') {
clearInterval(interval);
}
// otherwise do things
}, 100);

It’s common to call clearInterval inside the setInterval callback function, to let it auto-determine if it should run again or stop. For example this code runs something unless App.somethingIWait has the value arrived

setImmediate()

Any function passed as the setImmediate() argument is a callback that’s executed in the next iteration of the event loop.

Node.js also provides setImmediate(), which is equivalent to using setTimeout(() => {}, 0), mostly used to work with the Node.js Event Loop.

process.nextTick()

As you try to understand the Node.js event loop, one important part of it is process.nextTick(). Every time the event loop takes a full trip, we call it a tick.

process.nextTick() - we instruct the engine to invoke this function at the end of the current operation, before the next event loop tick starts:

Calling setTimeout(() => {}, 0) will execute the function at the end of next tick, much later than when using nextTick() which prioritizes the call and executes it just before the beginning of the next tick.

The Node.js Event emitter

On the backend side, Node.js offers us the option to build a event interaction system using the events module.

const EventEmitter = require('events');
const eventEmitter = new EventEmitter();

This object exposes, among many others, the on and emit methods.

  • emit is used to trigger an event
  • on is used to add a callback function that's going to be executed when the event is triggered

For example, let’s create a start event, and as a matter of providing a sample, we react to that by just logging to the console:

eventEmitter.on('start', () => {
console.log('started');
});
eventEmitter.emit('start');
  • once(): add a one-time listener
  • removeListener() / off(): remove an event listener from an event
  • removeAllListeners(): remove all listeners for an event

Node.js file stats

The fs.stat() method is used to return information about the given file or directory.

fs.stat( path, options, callback )
const fs = require('fs');
fs.stat('/Users/joe/test.txt', (err, stats) => {
if (err) {
console.error(err);
}
// we have access to the file stats in `stats`
});
  • if the file is a directory or a file, using stats.isFile() and stats.isDirectory()

Working with file descriptors in Node.js

To create the file, to write to a file, or to read a file fs.open() method is used. fs.readFile() is only for reading the file and similarly fs.writeFile() is only for writing to a file

fs.open( filename, flags, mode, callback )
  • flag: The operation in which the file has to be opened.

Reading files with Node.js

The simplest way to read a file in Node.js is to use the fs.readFile() method.

const fs = require('fs');
fs.readFile('/Users/joe/test.txt', 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
});

Writing files with Node.js

The easiest way to write to files in Node.js is to use the fs.writeFile() API.

const fs = require('fs');
const content = 'Some content!';
fs.writeFile('/Users/joe/test.txt', content, err => {
if (err) {
console.error(err);
}
// file written successfully
});

Working with folders in Node.js

Create a new folder

Use fs.mkdir() or fs.mkdirSync() or fsPromises.mkdir() to create a new folder.

Node.js File Paths

Every file in the system has a path. On Linux and macOS, a path might look like: /users/joe/file.txt

module allows you to retrieve and manipulate file paths.

You can join two or more parts of a path by using path.join():

onst name = 'joe';
path.join('/', 'users', name, 'notes.txt'); // '/users/joe/notes.txt'

You can get the absolute path calculation of a relative path using path.resolve():

path.resolve('joe.txt'); // '/Users/joe/joe.txt' if run from my home folder

How to read environment variables from Node.js

process.env — env property which hosts all the environment variables that were set at the moment the process was started.

process.env.USER_ID; // "239482"
process.env.USER_KEY; // "foobar"

If you have multiple environment variables in your node project, you can also create an .env file in the root directory of your project.

# .env file
USER_ID="239482"
USER_KEY="foobar"
NODE_ENV="development"
In your js file

require('dotenv').config();
process.env.USER_ID; // "239482"
process.env.USER_KEY; // "foobar"
process.env.NODE_ENV; // "development"

REPL — Node shell

REPL stands for Read Eval Print Loop and it represents a computer environment like a Windows console or Unix/Linux shell where a command is entered and the system responds with an output in an interactive mode.

  1. type node in your terminal
  2. type console.log(‘test’)
  3. type 5 === ‘5’

.help: shows the dot commands help

Accept input from the command line in Node.js

The node:readline module provides an interface for reading data from a Readable stream (such as process.stdin) one line at a time.

General Questions :

1. What do you know about RESTful APIs?

Representational State Transfer (REST) is an architectural style that defines a set of limitations or restrictions to be used for creating web services.

In HTTP there are five methods that are commonly used in a REST-based Architecture i.e., POST, GET, PUT, PATCH, and DELETE.

GET -is used to request data from a specified resource.

POST - is used to send data to a server to create/update a resource.(POST requests are never cached.POST requests do not remain in the browser history) -for example, customer information, file upload, etc. using HTML forms.

PUT -Replaces all current representations of the target resource with the uploaded content.

PATCH method updates an existing resource, with only partial data. In other words, you don’t need to supply the full representation of the new resource

2. SQL Databases for Node.js

3. Could you name some libraries that developers frequently use with Node.js?

  • Express. js. …
  • Lodash.
  • Mongoose. …
  • Axios.
  • Passport -Passport, the popular Express-compatible authentication middleware for Node.js. authenticates requests. Moreover, Passport does this through an extensible set of plugins.

4. Some disadvantages of Node.js.

Its performance is reduced with heavy computational tasks

It has tons of nested callbacks.Node.js relies heavily on callbacks.

4. How many API functions exist in Node.js? Could you name two?

API stands for Application Programming Interface. It consists of various communication protocols and subroutines that can be used by programs for inter-communication.

Types of API functions in Node.js:

  1. Asynchronous, Non-blocking functions -fs.readFile
  2. Synchronous, Blocking functions -fs.readFileSync

5. Please explain what Node.js streams are

Streams can be readable, writable, or both. All streams are instances of EventEmitter.Streams are objects that let you read data from a source or write data to a destination in a continuous fashion.

There are four fundamental stream types within Node.js:

  • Writable: streams to which data can be written (for example, fs.createWriteStream()).
  • Readable: streams from which data can be read (for example, fs.createReadStream()).
  • Duplex: streams that are both Readable and Writable (for example, net.Socket).
  • Transform: Duplex streams that can modify or transform the data as it is written and read (for example, zlib.createDeflate()).
var fs = require("fs");

// Create a readable stream
var readerStream = fs.createReadStream('input.txt');

// Create a writable stream
var writerStream = fs.createWriteStream('output.txt');

// Pipe the read and write operations
// read input.txt and write data to output.txt
readerStream.pipe(writerStream);

console.log("Program Ended");

Piping the Streams

Piping is a mechanism where we provide the output of one stream as the input to another stream. It is normally used to get data from one stream and to pass the output of that stream to another stream.

6. How the control flow function works?

The concept of control flow — a way of managing the flow of function calls in a Node.js program.The event loop is a key component of Node.js that manages the execution of functions and callbacks.

Control flow in Node.js is typically managed using one of three methods: callbacks, promises, and async/await.

7. Could you explain what the fork() method is?

Process management refers to the ways in which these processes are created, managed, and terminated.

There are three primary ways to create a child process in Node.js: exec, fork, and spawn.

  • child_process.exec() method: This method runs a command in a console and buffers the output.
  • child_process.spawn() method: This method launches a new process with a given command.
  • child_process.fork() method: This method is a special case of spawn() method to create child processes.

8. What is a buffer in Nodejs?

A buffer is a space in memory (typically RAM) that stores binary data. In Node. js, we can access these spaces of memory with the built-in Buffer class.

it is not necessary to import it using the require keyword.

Buffers store a sequence of integers, similar to an array in JavaScript.

It provides a fast and efficient way to store and manipulate binary data in Node. js.

9. Can you explain what reactor patterns are in Node.js?

This structure allows for non-blocking and asynchronous handling of I/O operations, making it well-suited for high-performance applications that rely heavily on event-driven programming.

To assign a hander(a callback) to each I/O operation in a system is called the Reactor Pattern. It’s the responsibilty of th system to run the handler function once the data from the event is available.

10. How different is Node.js from Ajax?

AJAX = Asynchronous JavaScript And XML.

AJAX is not a programming language.

AJAX just uses a combination of:

  • A browser built-in XMLHttpRequest object (to request data from a web server)
  • JavaScript and HTML DOM (to display or use the data)

Update a web page without reloading the page

Request data from a server — after the page has loaded

Receive data from a server — after the page has loaded

Send data to a server — in the background

11. What is XML?

  • XML stands for eXtensible Markup Language
  • XML is a markup language much like HTML
  • XML was designed to store and transport data
  • XML tags are not predefined like HTML tags are

12. What is the role of libuv in node?

Libuv is a library written in the programming language C that helps nodejs to improve efficiency while running tasks parallelly. However, nodejs already have async API’s. It uses Libuvs’s thread pools if async API is not available in nodejs and processes are blocking the operations.

13. What is thread pool?

In Node.js there are two types of threads:

Event Loop (aka the main loop, main thread, event thread, etc.)

Threadpool : Pool of k Workers in a Worker Pool

The libuv library maintains a pool of threads that are used by node.js to perform long-running operations in the background, without blocking its main thread.

A thread pool is a managed collection of threads that are available to perform tasks.

Node.js runs JavaScript code in the Event Loop (initialization and callbacks), and offers a Worker Pool to handle expensive tasks like file I/O.

14. What is Crypto module

Crypto module is one of the third-party modules that help encrypt or decrypt or hash any data. which we want to secure from outside the world. The main function of this module is to convert the plain text or data to the encrypted format(hashed, CipherText) which is non-readable.

15. Node.js Global Objects

Class: Buffer : The Buffer class is used to deal with binary data.

console: It is an inbuilt global object used to print to stdout and stderr.

process: It is an inbuilt global object that is an instance of EventEmitter used to get information on current process.

__filename

The filename of the script being executed. This is the absolute path

setTimeout(cb, ms)

16. Internet Status Codes

Success Codes : 200 OK,201 Created,202 Accepted,204-No content

Redirection Codes : 300 Multiple Choices,301 Moved Permanently

Client error Codes : 400 Bad Request,401 Unauthorized,402 Payment Required,403 Forbidden,404 Not Found

Server Error Codes : 500 Internal Server Error,501 Not Implemented,502 Bad Gateway,503 Service Unavailable

--

--