Understanding Node.js PDF
Document Details
Uploaded by Deleted User
Tags
Summary
This document provides an introduction to Node.js using JavaScript. It covers fundamental data types and concepts, such as variables, numbers, booleans, arrays, and objects. It also explains functions, closures, and object literals.
Full Transcript
UNDERSTANDING NODE.JS VARIABLES Variables are defined in JavaScript using the var keyword. var foo = 123; console.log(foo); // 123 The JavaScript runtime (the browser or Node.js) has the opportunity to define a few global variables that we can use in o...
UNDERSTANDING NODE.JS VARIABLES Variables are defined in JavaScript using the var keyword. var foo = 123; console.log(foo); // 123 The JavaScript runtime (the browser or Node.js) has the opportunity to define a few global variables that we can use in our code. One of them is the console object, which we have been using up to this point. The console object contains a member function (log), which takes any number of arguments and prints them to the console. We will discuss more global objects as they are used. As you will see, JavaScript contains most things you expect a good programming language to have NUMBERS All numbers in JavaScript have the same floating point number type. Arithmetic operations (+,-,*,/,%) work on numbers as you would expect. var foo = 3; var bar = 5; console.log(foo + 1); // 4 console.log(foo / bar); // 0.6 console.log(foo * bar); // 15 console.log(foo - bar); // -2; console.log(foo % 2); // remainder: 1 BOOLEAN Two literals are defined for boolean values: true and false. You can assign these to variables and apply boolean operations to them as you would expect. var foo = true; console.log(foo); // true // Boolean operations (&&, ||, !) work as expected: console.log(true && true); // true console.log(true && false); // false console.log(true || false); // true console.log(false || false); // false console.log(!true); // false console.log(!false); // true ARRAYS You can create arrays quite easily in JavaScript using []. Arrays have many useful functions, a few of which are shown below. var foo = []; foo.push(1); // add at the end console.log(foo); // prints foo.unshift(2); // add to the top console.log(foo); // prints [2,1] // Arrays are zero index based: console.log(foo); // prints 2 OBJECT LITERALS By explaining these few fundamental types, we have introduced you to object literals. The most common way of creating an object in JavaScript is using the object notation, {}. Objects can be extended arbitrarily at runtime. var foo = {}; console.log(foo); // {} foo.bar = 123; // extend foo foo.bar = 123; // extend foo OBJECT LITERALS Instead of extending it at runtime, you can define which properties go on an object upfront by using the object literal notation. var foo = { bar: 123 }; console.log(foo); // { bar: 123 } OBJECT LITERALS You can additionally nest object literals inside object literals, var foo = { bar: 123, bas: { bas1: 'some string', bas2: 345 } }; console.log(foo); OBJECT LITERALS And, of course, you can have arrays inside object literals as well, var foo = { bar: 123, bas: [1, 2, 3] }; console.log(foo); And, you can also have these arrays themselves contain object literals, var foo = { bar: 123, bas: [{ qux: 1 }, { qux: 2 }, { qux: 3 }] }; console.log(foo.bar); // 123 console.log(foo.bas.qux); // 1 console.log(foo.bas.qux); // 2 Object literals are extremely handy as function arguments and return values FUNCTIONS Functions are really powerful in JavaScript. Most of the power of JavaScript comes from the way it handles the function type A normal function structure in function foo() { return 123; } JavaScript console.log(foo()); // 123 function functionName() { // function body function bar() { } // optional return; console.log(bar()); // undefined } IMMEDIATELY EXECUTING FUNCTION You can execute a function immediately after you define it. Simply wrap the function in parentheses () and invoke it (function foo() { var foo = 123; console.log('foo was executed!'); if (true) { })(); (function () { // create a new scope var foo = 456; })(); } console.log(foo); // 123; ANONYMOUS FUNCTION A function without a name is called an anonymous function. In JavaScript, you can assign a function to a variable. If you are going to use a function as a variable, you don’t need to name the function. var foo1 = function namedFunction() { // no use of name, just wasted characters console.log('foo1'); } foo1(); // foo1 var foo2 = function () { // no function name given i.e. anonymous function console.log('foo2'); } foo2(); // foo2 A programming language is said to have first-class functions if a function can be treated the same way as any other variable in the language. JavaScript has first-class functions. HIGHER-ORDER FUNCTIONS Since JavaScript allows us to assign functions to variables, we can pass functions to other functions. Functions that take functions as arguments are called higher-order functions. A very common example of a higher-order function is setTimeout. setTimeout(function () { console.log('2000 milliseconds have passed since this demo started'); }, 2000); CLOSURES Whenever we have a function defined inside another function, the inner function has access to the variables declared in the outer function. function outerFunction(arg) { var variableInOuterFunction = arg; function bar() { console.log(variableInOuterFunction); // Access a variable from the outer scope } // Call the local function to demonstrate that it has access to arg bar(); } outerFunction('hello closure!'); // logs hello closure! UNDERSTANDING NODE.JS PERFORMANCE Node.js is focused on creating highly performant applications. In the following section, we introduce the I/O scaling problem. Then we show how it has been solved traditionally, followed by how Node.js solves it. The I/O Scaling Problem Node.js is focused on being the best way to write highly performant web applications. To understand how it achieves this, we need to know about the I/O scaling problem. Let us look at a rough estimate of the speed at which we can access data from various sources in terms of CPU cycles UNDERSTANDING NODE.JS PERFORMANCE UNDERSTANDING NODE.JS PERFORMANCE You can clearly see that Disk and Network access is in a completely different category from accessing data that is available in RAM and CPU cache. Most web applications depend on reading data from disk or from another network source (for example, a database query). When an HTTP request is received and we need to load data from a database, typically this request will be spent waiting for a disk read or a network access call to complete. These open connections and pending requests consume server resources (memory and CPU). In order to handle a large number of requests from different clients using the same web server, we have the I/O scaling problem. TRADITIONAL WEB SERVERS USING A PROCESS PER REQUEST Traditional servers used to spin up a new process to handle every single web request. Spinning a new process for each request is an expensive operation, both in terms of CPU and memory. This is the way technologies like PHP used to work when they were first created. A demonstration of this concept is shown in Figure 2-2. In order to successfully reply to an HTTP request “A,” we need some data from a database. This read can potentially take a long time. For this entire read duration, we will have a process taking up CPU and memory while idling and waiting for the database response. Also, processes are slow to start and have a significant overhead in terms of RAM space. This does not scale for very long and that is the reason why modern web applications use a thread pool. TRADITIONAL WEB SERVERS USING A THREAD POOL Modern servers use a thread from a thread pool to serve each request. Since we already have a few Operating System (OS) threads created (hence a thread pool), we do not pay the penalty of starting and stopping OS processes (which are expensive to create and take up much more memory than a thread). When a request comes in, we assign a thread to process this request. This thread is reserved for the request in the entire duration that the request is being handled, as demonstrated in Figure 2-3. THANK YOU !!!