0% found this document useful (0 votes)
22 views47 pages

Events

This document covers the use of events, listeners, timers, and callbacks in Node.js, emphasizing its single-threaded event-driven model that enhances scalability and performance. It explains how to implement HTTP services and Express in Node.js, along with the handling of blocking I/O and the event queue. Additionally, it details the creation and management of custom events and listeners using the EventEmitter object.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views47 pages

Events

This document covers the use of events, listeners, timers, and callbacks in Node.js, emphasizing its single-threaded event-driven model that enhances scalability and performance. It explains how to implement HTTP services and Express in Node.js, along with the handling of blocking I/O and the event queue. Additionally, it details the creation and management of custom events and listeners using the EventEmitter object.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 47

UNIT – III

• Using Events, Listeners, Timers, and Callbacks in Node.js:Node.js


Event Model, Adding Work to the Event Queue, Implementing
Callbacks
• Implementing HTTP Services in Node.js: Processing URLs,
Understanding Request, Response, and Server Objects, Implementing
HTTP Clients and Servers in Node.js, Implementing HTTPS Servers and
Clients
• Implementing Express in Node.js: Getting Started with Express,
Configuring Routes, Using Request/Responses Objects
Using Events, Listeners, Timers,
and Callbacks in Node.js
• Node.js provides scalability and performance through its powerful
event-driven model.
• Node.js applications run on a single thread rather than multiple
threads
• Using the single thread for application processing makes Node.js
processes more efficient and faster.
Summary
• This chapter focuses on understanding the model and how it differs
from traditional threading models used by most webservers.
• events can be added to the event queue when blocking I/O is called.
And listeners can be triggered by events or timers or called directly
using the nextTick() method.
• This chapter also covers the different methods you use to add work to
the Node.js event queue. You can add work using event listeners or
timers, or you can schedule work directly
• Node.js applications are run in a single-threaded event-driven
model. Although Node.js implements a thread pool in the
background to do work, the application itself doesn’t have any
concept of multiple threads.
Traditional Threaded web model
• In the traditional threaded web model, a request comes in to the
webserver and is assigned to an available thread. Then the handling of
work for that request continues on that thread until the request is
complete and a response is sent.
• Figure illustrates the threaded model processing two requests, GetFile
and GetData.
• The GetFile request first opens the file, reads the contents, and then
sends the data back in a response. All this occurs in order on the same
thread.
• The GetData request connects to the DB, queries the necessary data,
and then sends the data in the response.
• Node.js is a single-threaded runtime environment, but it also has multithreading
APIs.
• Single-threaded
• Node.js runs JavaScript code in a single thread, which means that it can only do one task
at a time
• The event loop, also known as the main thread, runs one thing at a time
• Single-threaded programming models are simpler to reason about
• Multithreaded
• Node.js exposes multithreading APIs, including the worker_threads module
• Node.js provides hidden threads through the libuv library, which handles I/O operations
• Advantages of single-threaded
• Reduces the overhead of thread communication
• Allows for a more quick response
• Can handle thousands of concurrent connections with minimal resource usage
• Well-suited for I/O-heavy applications, such as web servers, APIs, and real-time
applications
• The Node.js event model does things differently. Instead of executing
all the work for each request on individual threads, work is added to
an event queue and then picked up by a single thread running an event
loop.
• The event loop grabs the top item in the event queue, executes it, and
then grabs the next item. When executing code that is no longer live or
has blocking I/O, instead of calling the function directly, the function is
added to the event queue along with a callback that is executed after
the function completes.
• When all events on the Node.js event queue have been executed, the
Node application terminates.
• Figure illustrates the way Node.js handles the GetFile and GetData requests.
• The GetFile and GetData requests are added to the event queue.
• Node.js first picks up the GetFile request, executes it, and then completes by
adding the
• Open() callback function to the event queue.
• Next, it picks up the GetData request, executes it, and completes by adding the
Connect() callback function to the event queue. This continues until there are
no callback functions to be executed.
• Notice in Figure that the events for each thread do not necessarily follow a
direct interleaved order. For example, the Connect request takes longer to
complete than the Read request, so Send(file) is called before Query(db).
Blocking I/O in Node.js

• The Node.js event model of using the event callbacks is great until
you run into the problem of functions that block waiting for I/O.
Blocking I/O stops the execution of the current thread and waits for a
response before continuing.
Some examples of
• blocking I/O are
• Reading a file
• Querying a database
• Socket request
• Accessing a remote service
Node.js event model
Node.js event model
• Figure illustrates the full Node.js event model including the
• Event queue,
• Event loop,
• and the thread pool.
• Notice that the event loop either executes the function on the event
loop thread itself or, for blocking I/O, it executes the function on a
separate thread.
Node.js event model
• Figure In the Node.js event model, work is added as a function with
callback to the event queue, and then picked up on the event loop
thread.
• The function is then executed on the event loop thread in the case of
non-blocking, or on a separate thread in the case of blocking
• Node.js uses event callbacks is not to have to wait for blocking I/O.
• Therefore, any requests that perform blocking I/O are performed on a
different thread in the background. Node.js implements a thread pool
in the background.
• When an event that requires blocking I/O is retrieved from the event
queue, Node.js retrieves a thread from the thread pool and executes
the function there instead of on the main event loop thread. This
prevents the blocking I/O from holding up the rest of the events in the
event queue.
• The function executed on the blocking thread can still add events
back to the event queue to be processed. For example, a database
query call is typically passed a callback function that parses the results
and may schedule additional work on the event queue before sending
a response.
Adding Work to the Event
Queue
• As you create your Node.js applications, keep in mind the event
model
• To leverage the scalability and performance of the event model, make
sure that you break work upinto chunks that can be performed as a
series of callbacks.
• Once you have designed your code correctly, you can then use the
event model to schedule work on the event queue.
• In Node.js applications, work is scheduled on the event queue by
passing a callback function using one of these methods:
1. Make a call to one of the blocking I/O library calls such as writing to
a file or connecting to a database.
2. Add a built-in event listener to a built-in event such as an
http.request or server.connection.
3. Create your own event emitters and add custom listeners to them.
4. Use the process.nextTick option to schedule work to be picked up
on the next cycle of the event loop.
5. Use timers to schedule work to be done after a particular amount of
time or at periodic intervals.
Implementing Timers

• A useful feature of Node.js and JavaScript is the ability to delay


execution of code for a period of time. This can be useful for cleanup
or refresh work that you do not want to always be running.
• There are three types of timers you can implement in Node.js:
1. timeout,
2. interval,
3. and immediate.
Delaying Work with Timeouts
• Timeout timers are used to delay work for a specific amount of time.
When that time expires, the callback function is executed and the
timer goes away.
• Use timeouts for work that only needs to be performed once.
• Timeout timers are created using the setTimeout(callback,
• delayMilliSeconds, [args]) method built into Node.js.
• When you call setTimeout(), the callback function is executed after
delayMilliSeconds expires.
• The setTimeout() function returns a timer object ID. You can pass this
ID to clearTimeout(timeoutId) at any time before the
delayMilliSeconds expires to cancel the timeout function. For
example:
• myTimeout = setTimeout(myFunc, 100000);
• … clearTimeout(myTimeout);
function simpleTimeout(consoleTimer){
console.timeEnd(consoleTimer);
}
console.time("twoSecond");
setTimeout(simpleTimeout, 2000, "twoSecond");
console.time("oneSecond");
setTimeout(simpleTimeout, 1000, "oneSecond");
console.time("fiveSecond");
setTimeout(simpleTimeout, 5000, "fiveSecond");
console.time("50MilliSecond");
setTimeout(simpleTimeout, 50, "50MilliSecond");
• events can be added to the event queue when blocking I/O is called.
And you learned that listeners can be triggered by events or timers or
called directly using the nextTick() method.
• A normal function is called directly, while a callback function is initially only
defined. The callback function is only called and executed once a specific event has
occurred
function getDetails(){
setTimeout(() => {
console.log("DETAILS")
}, 2000);
}
function getUser(){
setTimeout(() => {
console.log("USER");
callback(); // Calling the function
}, 3000);
}
Performing Periodic Work with
Intervals
• Interval timers are used to perform work on a regular delayed
interval. When the delay time expires, the callback function is
executed and is then rescheduled for the delay interval again.
• Use intervals for work that needs to be performed on a regular basis.
• Interval timers are created using the setInterval(callback,
delayMilliSeconds, [args]) method built into Node.js.
• When you call setInterval(), the callback function is executed every
interval after delayMilliSeconds has expired. For example, the
following executes
myFunc() every second:
setInterval(myFunc, 1000);
• The setInterval() function returns a timer object ID. You can pass this
ID to clearInterval(intervalId) at any time before the
delayMilliSeconds expires to cancel the timeout function. For
example:
• myInterval = setInterval(myFunc, 100000);
• … clearInterval(myInterval);
Performing Immediate Work
with an Immediate Timer
• Immediate timers are used to perform work on a function as soon as the
I/O event callbacks are executed, but before any timeout or interval events
are executed.
• This allows you to schedule work to be done after the current events in the
event queue are completed.
• Use immediate timers to yield long-running execution segments to other
callbacks to prevent starving the I/O events.
• Immediate timers are created using the setImmediate(callback,[args])
method built into Node.js.
• When you call setImmediate(), the callback function is placed on the event
queue and popped off once for each iteration through the event queue
loop after I/O events have a chance to be called.
• The setImmediate() function returns a timer object ID. You can pass
this ID to clearImmediate(immediateId) at any time before it is picked
up off the event queue. For example:
myImmediate = setImmediate(myFunc);

clearImmediate(myImmediate);
Dereferencing Timers from the
Event Loop
• Often you do not want timer event callbacks to continue to be
scheduled when they are the only events left in the event queue.
• Node.js provides a useful utility to handle this case. The unref() function
available in the object returned by setInterval and setTimeout allows
you to notify the event loop to not continue when these are the only
events on the queue.
• For example, the following dereferences the myInterval interval timer:
• myInterval = setInterval(myFunc);
• myInterval.unref();
• you can use the ref() function to rereference it: myInterval.ref();
Using nextTick to Schedule
Work
• A useful method of scheduling work on the event queue is the
process.nextTick(callback) function.
• This function schedules work to be run on the next cycle of the event
loop. Unlike the setImmediate() method,nextTick() executes before
the I/O events are fired.
• This can result in starvation of the I/O events, so Node.js limits the
number of nextTick() events that can be executed each cycle through
the event queue by the value of process.maxTickDepth, which
defaults to 1000.
Implementing Event Emitters
and Listeners
• to implement many of the events built in to the various Node.js modules. This
section focuses on creating your own custom events as well as implementing
listener callbacks that get implemented when an event is emitted.
• Events are emitted using an EventEmitter object. This object is included in the
• events module.
• The emit(eventName, [args]) function triggers the eventName event and
includes any arguments provided.
• The following code snippet shows how to implement a simple event emitter:
var events = require('events');
var emitter = new events.EventEmitter();
emitter.emit("simpleEvent");
Function MyObj(){
Events.EventEmitter.call(this);
}
MyObj.prototype.__proto__ = events.EventEmitter.prototype;
You then can emit events directly from instances of your object. For
example:
var myObj = new MyObj();
myObj.emit("someEvent")
Adding Event Listeners to
Objects
• Once you have an instance of an object that can emit events, you can
add listeners for the events that you care about. Listeners are added to
an EventEmitter object using one of the following functions:
1. .addListener(eventName, callback): Attaches the callback function to
the object’s listeners. Every time the eventName event is triggered,
the callback function is placed in the event queue to be executed.
2. .on(eventName, callback): Same as .addListener().
3. .once(eventName, callback): Only the first time the eventName
event is triggered, the callback function is placed in the event queue
to be executed.
Removing Listeners from
Objects
• Node.js provides server helper functions on the EventEmitter object
that allow you to manage the listeners that are included. These
include
1. .listeners(eventName): Returns an array of listener functions
attached to the eventName event.
2. .setMaxListeners(n): Triggers a warning if more than n listeners are
added to an EventEmitter object. The default is 10.
3. .removeListener(eventName, callback): Removes the callback
function from the eventName event of the EventEmitter object.
I will call back later!“(Call Back
Function)
• A callback is a function passed as an argument to another function
• This technique allows a function to call another function
• A callback function can run after another function has finished
• A callback function is a function passed into another function as an
argument, which is then invoked inside the outer function to
complete some kind of routine or action.
• Callback functions are functions that are called after the first function
completes its task. They are often used to handle asynchronous
events and make your code more readable.
• JavaScript callback functions are important for the following reasons:
• They allow you to handle events. Events in your JavaScript program include things like a user pressing a
button or a network request concluding. Callbacks allow events to be handled as they happen.
• You can use them to send asynchronous API calls. Many APIs are asynchronous, which means they don’t
immediately return a value. They instead give back a promise or a callback method. When the API call is
finished, the callback function is invoked.
• You can use them to enhance your code’s performance. Callbacks enable you to multitask while an
asynchronous action is running, which can help your code execute faster.
• Callback functions can be used to manage the flow of asynchronous operations, preventing the infamous
“callback hell.” This is a situation where deeply nested callbacks make code hard to read and maintain.
• Closures, which allow functions to “remember” the scope in which they were generated, are frequently
used by callback functions. This has the potential to be very effective at preserving state and encapsulating
behavior.
• Higher-order functions, or functions that can take other functions as inputs or return other functions as
values, are based on the concept of callbacks. This functional programming patte
• Update the UI after a network request has completed.
• Process data after a file has been read.
• Make another API call after the results of the first API call have been
received.
• Node Callback Concept
• A callback in Node is a non-blocking function that executes upon task
completion, enabling asynchronous processing. It facilitates scalability
by allowing Nodejs to handle multiple requests without waiting for
operations to conclude, in file I/O scenarios.
• Explanation: The fs library is used for file-system operations. The
readFileSync() function is synchronous, halting program execution
until completion. This blocking behavior ensures that the program
reads the file before progressing further.
Callback Implementation
setTimeout() triggers an asynchronous
process; it will not wait for the callback to
get executed. It returns quickly, providing
function exampleAsync(a, b, callback) { the control back to exampleAsync(), and
then back to its caller.
setTimeout(function() {
callback(a + b);
}, 100);
}
console.log('Before asynchronous call’);
exampleAsync(2, 3, function(finalresult)
{
console.log('Result: ' + finalresult);
}); console.log('After asynchronous call')
const fs = require('fs');
fs.readFile('./1.txt', { encoding: 'utf8', flag: 'r' },
A callback is a function called when the task
function (err, data1) { finishes, and a callback function allows other code
to run in the meantime. Using the Callback
if (err) concept, Node.js can process many requests
without waiting for any function to return the
console.log(err); result, making Node.js highly scalable. For
else example: In Node.js, when a function starts
reading the file, it returns the control to the
console.log(data1); execution environment immediately to execute the
next instruction. Once file I/O gets completed, the
}); callback function will get called to avoid blocking
or wait for File I/O.
console.log("EXECUTION ENDS");
Implementing Closure in
Callbacks
• An interesting problem that asynchronous callbacks have is that of
closure.
• Closure is a JavaScript term that indicates that variables are bound to
a function’s scope and not the parent function’s scope.
• When you execute an asynchronous callback, the parent function’s
scope may have changed;
• for example, when iterating through a list and altering values in each
iteration.
• If your callback needs access to variables in the parent function’s
scope, then you need to provide closure so that those values are
available when the callback is pulled off the event queue.
• A basic way of doing that is by encapsulating the asynchronous call
inside a function block and passing in the variables that are needed.
Fs module(const fs = require('fs');)
• Use fs.readFileSync() :
• When you are working with small files, such as configuration or startup files, where
blocking the execution won’t impact performance.
• In scenarios where synchronous execution is required, such as in scripts that run before
the event loop starts.
• When working with single-threaded, short-lived programs, like command-line utilities.
• Use fs.readFile() :
• When performance and scalability are critical, such as in web servers handling multiple
requests.
• For non-blocking, event-driven architectures where I/O operations should not block the
event loop.
• In production environments where multiple file reads can happen concurrently, and
blocking could result in significant performance degradation

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy