Introducción práctica a

para



Día 1: módulo HTTP, callbacks

Vuestro anfitrión

Alex Fernández

Ingeniero senior en LogTrust

Co-organizador de Node.js Madrid

@pinchito

Índice día 1


  • Introducción a Node.js.

  • Módulo http(s).

  • Sesión práctica 1: Hola, mundo! (versión web).

  • Callbacks y continuaciones.

  • Librería async.

  • Sesión práctica 2: Llamadas asíncronas


Introducción

A Node.js

Pero primero, un chiste


- Oye, , ¿cómo es que eres tan rápido? 

+ Es que yo soy async.


Fuente: pinchito

JavaScript en el servidor

Motor de JS en Chrome: V8 (en cómic)

Librería de eventos libuv

Combinados por Ryan Dahl


Software libre ( conoce tu software)

Soporte de Joyent

Casos de Éxito


PayPal

Walmart

LinkedIn


El Corte Inglés (search?)

Zara.com (search?)

ING Direct (search?)

LogTrust

Modelo de ejecución

Asíncrono

No bloqueante

Event-driven


Servidores similares:

Python: Tornado, Twisted

Ruby: EventMachine

Java: Akka


Fuentes: nodejs.org/about, Wikipedia

¿Eventos? ¿Por qué no hilos?


Un programador tenía un problema.

Pensó para sí mismo,

"Ya sé, ¡lo resolveré con hilos!".

tiene Ahora problemas. dos

Adaptado de: Davidlohr Bueso

Tres generaciones


Procesos: CGI, PHP core


Hilos: Apache MTM, Java Servlets


Eventos: nginx, node.js


Eventos all over the world


Node.js es rápido

Pero, ¿es de verdad tan rápido?


No con código secuencial...

pero sí en ejecución concurrente


Sólo tiene un hilo de ejecución (básicamente sin hilos)

Multi-proceso usando el módulo cluster


Node.js es muy escalable

Node.js es muy lineal

Módulo HTTP(s)

Módulos HTTP y httpS


Recibe peticiones HTTP


Devuelve una respuesta


Idéntico uso para http y https


Documentación

Sesión Práctica 1


Crea un servidor HTTP


Devuelve una página simplona


Muestra la URL de origen


Accede al servidor

Especificación Técnica


Servidor HTTP que escucha en el puerto 8000


Ante cualquier petición, devuelve una página web

<html><body>
  <h1>My web server</h1>
  <p>Received request for [path]</p>
</body></html>

En [path] metemos la URL pedida

Ayuda de HTTP

Create server

var server = http.createServer(handleRequest) 

Listen on port

server.listen(port);

Handle request

function handleRequest(request, response) { … } 

Write on response and close

response.end(data); 

Get URL of request

console.log(request.url); 

Good job!


Bonus Track


Mostrar una traza con el tiempo de cada petición


Responder HTTP 200 sólo a /ok


Responder HTTP 302 a otras rutas

Callbacks

y Continuaciones

Callbacks


De la intro oficial a Node.js:

const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end('Hello World\n');
});

server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
});

Callbacks en amarillo

¿Qué es una callback?


Una callback es una función


Una callback es una respuesta a un evento


Una callback es una continuación

Continuaciones

Continuation-passing Style

Continuaciones (Cont.)


Concepto de programación funcional


CPS: Continuation-passing Style


¡También conocidas como callbacks!


El estado pasa como parámetros y clausuras


Ideal para llamadas asíncronas

Ejemplo de continuaciones


const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end('Hello World\n');
});

server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
});

Continuaciones en amarillo
Parámetros en magenta
Clausuras en celeste

Niveles de ejecución


const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});


Contiene dos niveles de ejecución asíncrona

Sesión Práctica 2


Recuperar el código del servidor web

de la sesión práctica 1


Marcar:

  • callbacks,
  • continuaciones,
  • parámetros,
  • clausuras.

Bonus Track


Promesas


Async/await


Fuente

Librería Async

Ejecución asíncrona


Corre varias funciones una tras otra


Puede ir en serie o en paralelo


Devuelve error inmediatamente


Agrupa los resultados

Uso de Async


Ejecución en serie

async.series(tasks, callback); 


Ejecución en paralelo

async.parallel(tasks, callback); 


Ejecución en cascada

async.waterfall(tasks, callback); 

Funciones a Ejecutar


Función síncrona

function f1(callback) {
    return callback(null, 2);
} 


Función asíncrona

function f2(callback) {
    var filename = 'myfile.txt';
    fs.readFile(filename, (error, contents) => {
        if (error) return callback(error);
        console.log('Read file %s', filename);
        return callback(null, contents);
    }
} 

Resultado de Async


Funciones en array => resultados en array

async.series([f1, f2], (error, result) => {
    console.log('Result %j', result);
}

  \=> Result [1, 2] 


Funciones en objeto => resultados en objeto

async.series({first: f1, second: f2}, (error, result) => {
    console.log('Result %j', result);
});
 
    \=> Result {"first": 1, "second": 2}


Sesión Práctica 3


Instalar async:

npm install async 


Acceder a varias cuentas online


Sumar las deudas de cada cuenta


Mostrar el resultado

Especificación técnica



Ayuda

JSON.parse()

var parsed = JSON.parse(string); 

Ejecución en serie

async.series(tasks, (error, result) => { … }); 

Acceso HTTP a URL

http.get('http://nodejs.org/dist/index.json', (res) => {
  if (res.statusCode !== 200) {
    return console.error(‘Invalid status code ${res.statusCode}`);
  }
  let rawData = '';
  res.on('data', (chunk) => rawData += chunk);
  res.on('end', () => console.log(`Result: ${rawData}`);
}).on('error', (e) => {
  console.error(`Got error: ${e.message}`);
});

Success!

Mi solución


github.com/alexfernandez/curso-kairos/blob/master/lib/async.js


¡Intentad la vuestra antes de mirar!

Bonus Points


Lanzar la ejecución de forma paralela


Mostrar una traza por cada lectura


Leer ficheros de 01 a 10


Usar basic-request

Fin del primer día

Introducción práctica a Node.js, día 1

By Alex Fernández

Introducción práctica a Node.js, día 1

Curso de Node.js para Kairós, día 1: módulo HTTP, callbacks. 2018-02-23.

  • 2,464