Node Fundamentals

Leon Noel

RC Ascend

"I can't go to Outback, I got too much at stake"

Agenda

  • Questions? 

  • Let's Talk -  RC Ascend

  • Learn - JS All Lies 

  • Learn - Call Stack / Task Queue

  • Learn - Event Loop

  • Learn - Node 

  • Homework - part 4 & 5? 

Questions

About last class or life

PUSH EVERY DAY

Spaced Repetition

Ali Abdaal: https://youtu.be/Z-zNHHpXoMM

Thank You

Watch These Videos (Homework)

Backend!

Butt first!

Javascript is

single-threaded

Synchronous aka processes

one operation at a time

 

vs

If synchronous, how do we do stuff like make an api request and keep scrolling or clicking

Things should block

THE ENVIRONMENT

Not This

THIS

Our JS is running in

a browser

 

Browsers have a BUNCH of APIs we can use that are async and enable us to keeping looking a cute cat photos while those operations are being processed asynchronously

Common browser APIs

WAIT
WHAT THE FUCK

Actual words Leon said when figuring all this shit out...

So, yeah, JS can do a lot of "blocking" stuff in the browser because it is handing that stuff off to async

Web APIs

BUT

We are going to need to know how to handle responses coming back from those Web APIs

 

JS does this with callbacks, promises,

and eventually async/await

The Old School Way

Callbacks

You can have a function that takes another function as an argument

aka Higher Order Function

You have seen this a million times

addEventListener('click', callback)

A Callback is the function that has been passed as an argument

Callbacks are not really "a thing" in JS

just a convention 

Callback fires when async task or another function

 is done

function houseOne(){
    setTimeout(() => {
        console.log('Paper delivered to house 1')
        setTimeout(() => {
            console.log('Paper delivered to house 2')
            setTimeout(() => {
                console.log('Paper delivered to house 3')
            }, 3000)
        }, 4000)
    }, 5000)
}
houseOne()

Welcome To Hell

Callback Hell

What if there was a more readable way to handle async code

Promise

An object that MAY have a value in

the future

.then()

A promise object method that runs after the promise "resolves"

 

.then(value)

Whatever value the promise object has gets passed as an argument

 

We've Seen This Before

APIs

Fetch Fido, Fetch!

fetch("https://dog.ceo/api/breeds/image/random")
    .then(res => res.json()) // parse response as JSON
    .then(data => {
      console.log(data)
    })
    .catch(err => {
        console.log(`error ${err}`)
    });

Fetch returns a Promise

Like a bunch of Web APIs running async code

function houseOne(){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Paper delivered to house 1')
        }, 1000)
    })
}
function houseTwo(){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Paper delivered to house 2')
        }, 5000)
    })
}
function houseThree(){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Paper delivered to house 3')
        }, 2000)
    })
}
houseOne()
    .then(data => console.log(data))
    .then(houseTwo)
    .then(data => console.log(data))
    .then(houseThree)
    .then(data => console.log(data))
    .catch(err => console.log(err))

Chaining Don't Read Good

I want my asynchronous code to look sychronous

Async / Await

A way to handle async responses

Promises Under The Hood

Await waits for an async process to complete inside an Async Function

function houseOne(){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Paper delivered to house 1')
        }, 1000)
    })
}
function houseTwo(){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Paper delivered to house 2')
        }, 5000)
    })
}
function houseThree(){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Paper delivered to house 3')
        }, 2000)
    })
}
async function getPaid(){
    const houseOneWait = await houseOne()
    const houseTwoWait = await houseTwo()
    const houseThreeWait = await houseThree()
    console.log(houseOneWait)
    console.log(houseTwoWait)
    console.log(houseThreeWait)
}
getPaid()
async function getPaid(){
    const houseOneWait = await houseOne()
    const houseTwoWait = await houseTwo()
    const houseThreeWait = await houseThree()
    console.log(houseOneWait)
    console.log(houseTwoWait)
    console.log(houseThreeWait)
}
getPaid()

I Need Something Real

APIs

Fetch Fido, Fetch!

async function getACuteDogPhoto(){
    const res = await fetch('https://dog.ceo/api/breeds/image/random')
    const data = await res.json()
    console.log(data)
}
getACuteDogPhoto()

Let's Use A Web API 

setTimeout()

setTimeout and setInterval are not part of the Javascript specification...

 

Most environments include them...

like all browsers and Node.js

function houseOne(){
    console.log('Paper delivered to house 1')
}
function houseTwo(){
    setTimeout(() => console.log('Paper delivered to house 2'), 3000)
}
function houseThree(){
    console.log('Paper delivered to house 3')
}
houseOne()
houseTwo()
houseThree()
function houseOne(){
    console.log('Paper delivered to house 1')
}
function houseTwo(){
    setTimeout(() => console.log('Paper delivered to house 2'), 0)
}
function houseThree(){
    console.log('Paper delivered to house 3')
}
houseOne()
houseTwo()
houseThree()

EVENT LOOP

Time for some data structures

Queue

Like a real queue, the first element which was added to the list, will be the first element out.

This is called a FIFO (First In First Out) structure.

let queue = []
queue.push(2) // queue is now [2] 
queue.push(5) // queue is now [2, 5] 
let i = queue.shift() // queue is now [5] 
alert(i) // displays 2

Queue Example

Stack

The first pancake made, is the last pancake served.

This is called a stack.

The first element which was added to the list, will be the last one out. This is called a LIFO (Last In First Out) structure.

let stack = []
stack.push(2) // stack is now [2] 
stack.push(5) // stack is now [2, 5] 
let = stack.pop() // stack is now [2] 
alert(i) // displays 5

Stack Example

Back To Getting Got

JS IS RUNNING IN THE BROWSER

 

V8 Engine
(Parse Code > Runnable Commands)

 

Window Runtime (Hosting Environment)

Gives Us Access To Web APIs

Passes stuff to Libevent (Event Loop)

The Event Loop monitors the Callback Queue and Job Queue and decides what needs to be pushed to the Call Stack.

Call Stack

Web APIs

Task Queue

(Also, a job queue)

console.log('Paper delivered to house 1')

setTimeout(() => {
  console.log('Paper delivered to house 2'), 0)
}

console.log('Paper delivered to house 3')

Console

main()

Call Stack

Web APIs

Task Queue

(Also, a job queue)

console.log('Paper delivered to house 1')

setTimeout(() => {
  console.log('Paper delivered to house 2'), 0)
}

console.log('Paper delivered to house 3')

Console

main()

log('house 1')

Call Stack

Web APIs

Task Queue

(Also, a job queue)

console.log('Paper delivered to house 1')

setTimeout(() => {
  console.log('Paper delivered to house 2'), 0)
}

console.log('Paper delivered to house 3')

Console

main()

log('house 1')

Call Stack

Web APIs

Task Queue

(Also, a job queue)

console.log('Paper delivered to house 1')

setTimeout(() => {
  console.log('Paper delivered to house 2'), 0)
}

console.log('Paper delivered to house 3')

Console

main()

log('house 1')

setTimeout()

Call Stack

Web APIs

Task Queue

(Also, a job queue)

console.log('Paper delivered to house 1')

setTimeout(() => {
  console.log('Paper delivered to house 2'), 0)
}

console.log('Paper delivered to house 3')

Console

main()

log('house 1')

setTimeout()

Call Stack

Web APIs

Task Queue

(Also, a job queue)

console.log('Paper delivered to house 1')

setTimeout(() => {
  console.log('Paper delivered to house 2'), 0)
}

console.log('Paper delivered to house 3')

Console

main()

log('house 1')

setTimeout() - cb or promise...

log('house 3')

Call Stack

Web APIs

Task Queue

(Also, a job queue)

console.log('Paper delivered to house 1')

setTimeout(() => {
  console.log('Paper delivered to house 2'), 0)
}

console.log('Paper delivered to house 3')

Console

log('house 1')

setTimeout() - cb or promise...

log('house 3')

Call Stack

Web APIs

Task Queue

(Also, a job queue)

console.log('Paper delivered to house 1')

setTimeout(() => {
  console.log('Paper delivered to house 2'), 0)
}

console.log('Paper delivered to house 3')

Console

cb / promise

log('house 1')

log('house 3')

Call Stack

Web APIs

Task Queue

(Also, a job queue)

console.log('Paper delivered to house 1')

setTimeout(() => {
  console.log('Paper delivered to house 2'), 0)
}

console.log('Paper delivered to house 3')

Console

log('house 1')

log('house 3')

log('house 2')

Backend BABY

Does Javascript have access to the DOM natively (built in)?

Javascript needed Web APIs to handle async and a bunch of stuff in the Browser 

JS is a language that can only do what the hosting environment allows

What Do Servers Need?

Disk Access

(hardrive/ssd)

&&

Network Access

(internet, request / responses)

What if there was a hosting environment that allowed JS to have disk and network access

Music & Light Warning - Next Slide

NODE.js BABY

Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine.

The same shit that lets you run JS in the browser can now be used to run JS on Servers, Desktops, and elsewhere

True Story

V8 Engine Does All The Heavy Lifting

Engine Vs. Compiler

And just like the browser's Web APIs Node come with a bunch of stuff

Built in Modules

(libraries or collections of functions)

 

HTTP (network access)

FS (file system access)

Access to millions of packages via NPM

(groupings of one or more custom modules)

Not Web APIs, but C/C++ APIs

sorry, don't remember the source

Releases?

LTS, Current, Nightly?

Let's Code

Simple Node Server

Just

HTTP & FS

const http = require('http')
const fs = require('fs')
http.createServer((req, res) => {
  fs.readFile('demofile.html', (err, data) => {
    res.writeHead(200, {'Content-Type': 'text/html'})
    res.write(data)
    res.end()
  })
}).listen(8000)

Music & Light Warning - Next Slide

You are now a

Software Engineer

that can build

Fullstack Web Applications

Let's Look

More Complex Backend

How could we clean this up?

Group Work

Homework

RC Ascend - Node Fundamentals

By Leon Noel

RC Ascend - Node Fundamentals

  • 398