Alex Fernández
Ingeniero senior en LogTrust
Co-organizador de Node.js Madrid
- Oye,
#
nodejs
, ¿cómo es que eres tan rápido?
+ Es que yo soy async.
Fuente:
pinchito
Motor de JS en Chrome: V8 (en cómic)
Librería de eventos libuv
Combinados por Ryan Dahl
Soporte de
Joyent
El Corte Inglés (search?)
Zara.com (search?)
ING Direct (search?)
LogTrust
Asíncrono
No bloqueante
Event-driven
Servidores similares:
Ruby: EventMachine
Java: Akka
Fuentes:
nodejs.org/about,
Wikipedia
Un programador tenía un problema.
Pensó para sí mismo,
"Ya sé, ¡lo resolveré con hilos!".
tiene Ahora problemas. dos
Adaptado de:
Davidlohr Bueso
Hilos:
Apache MTM,
Java Servlets
Eventos:
nginx, node.js
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
Recibe peticiones HTTP
Devuelve una respuesta
Idéntico uso para http y https
Crea un servidor HTTP
Devuelve una página simplona
Muestra la URL de origen
Accede al servidor
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>
[path]
metemos la URL pedida
var server = http.createServer(handleRequest)
server.listen(port);
function handleRequest(request, response) { … }
response.end(data);
console.log(request.url);
Mostrar una traza con el tiempo de cada petición
Responder HTTP 200 sólo a /ok
Responder HTTP 302 a otras rutas
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}/`);
});
Una callback es una función
Una callback es una respuesta a un evento
Una callback es una continuación
Concepto de programación funcional
CPS: Continuation-passing Style
¡También conocidas como callbacks!
El estado pasa como parámetros y clausuras
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
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
Recuperar el código del servidor web
de la sesión práctica 1
Marcar:
Promesas
Async/await
Corre varias funciones una tras otra
Puede ir en serie o en paralelo
Devuelve error inmediatamente
Agrupa los resultados
async.series(tasks, callback);
async.parallel(tasks, callback);
async.waterfall(tasks, callback);
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);
}
}
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}
Instalar async:
npm install async
Acceder a varias cuentas online
Sumar las deudas de cada cuenta
Mostrar el resultado
var parsed = JSON.parse(string);
async.series(tasks, (error, result) => { … });
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}`);
});
github.com/alexfernandez/curso-kairos/blob/master/lib/async.js
¡Intentad la vuestra antes de mirar!
Lanzar la ejecución de forma paralela
Mostrar una traza por cada lectura
Leer ficheros de 01 a 10
Usar
basic-request