Piero Divasto
Full-stack developer
T1
T2
T3
T1
T2
T3
Tiempo
CPU 1
CPU 2
T1
T2
T3
T1
T2
T3
Tiempo
CPU 1
T1
T2
T3
T1
T2
T3
JavaScript is a prototype-based, multi-paradigm, dynamic language, single-threaded, supporting object-oriented, imperative, and declarative (e.g. functional programming) styles.
https://developer.mozilla.org/en-US/docs/Web/JavaScript
https://www.youtube.com/watch?v=CuwGYz2WgFs&t=1980s
El modelo de concurrencia de JavaScript es como tener un restaurant el cual tiene una cantidad infinita de mesas y que puedes sentar la cantidad de personas que quieras, pero que tiene una sola cocina.
stack
task queue
Web Api
heap
stack
Web Api
console
code
console.log("Hola!")
setTimeout(function() {
console.log("La Previa 2023!");
}, 3000)
console.log("Saludos!");
task queue
stack
Web Api
console
code
console.log("Hola!") <-----
setTimeout(function() {
console.log("Codeton 2020!");
})
console.log("Saludos!");
main()
console.log("Hola!");
console.log("Hola!") <----
setTimeout(function() {
console.log("La Previa 2023!");
}, 3000)
console.log("Saludos!");
task queue
stack
Web Api
console
code
console.log("Hola!") <-----
setTimeout(function() {
console.log("La Previa 2023!");
})
console.log("Saludos!");
console.log("Hola!");
task queue
stack
Web Api
console
code
console.log("Hola!")
setTimeout(function() { <-----
console.log("La Previa 2023!");
}, 3000);
console.log("Saludos!");
> "Hola!"
setTimeout(...)
task queue
stack
Web Api
console
code
console.log("Hola!")
setTimeout(function() {
console.log("La Previa 2023!");
}, 3000);
console.log("Saludos!");
> "Hola!"
timeout(3 secs)
task queue
stack
Web Api
console
code
console.log("Hola!")
setTimeout(function() {
console.log("La Previa 2023!");
});
console.log("Saludos!"); <----
> "Hola!"
timeout(3 secs)
console.log("Sal...");
task queue
stack
Web Api
console
code
console.log("Hola!")
setTimeout(function() {
console.log("La Previa 2023!");
});
console.log("Saludos!");
> "Hola!"
timeout(3 secs)
> "Saludos!"
task queue
stack
Web Api
console
code
console.log("Hola!")
setTimeout(function() {
console.log("La Previa 2023!");
});
console.log("Saludos!");
> "Hola!"
timeout()
> "Saludos!"
task queue
stack
Web Api
console
code
console.log("Hola!")
setTimeout(function() {
console.log("La Previa 2023!");
}, 3000);
console.log("Saludos!");
> "Hola!"
> "Saludos!"
task queue
timeout()
stack
Web Api
console
code
console.log("Hola!")
setTimeout(function() {
console.log("La Previa 2023!");
}, 3000);
console.log("Saludos!");
> "Hola!"
> "Saludos!"
> "Codeton 2020!"
task queue
Callbacks
Promises
Generators
async/await
Callbacks
function greeting(name) {
alert('Hello ' + name);
}
function processUserInput(callback) {
var name = prompt('Please enter your name.');
callback(name);
}
processUserInput(greeting);
Callbacks
// Ir a un local y comprar un completo
irAlLocal(direccion, function hacerPedido(err) {
if (err) {
console.error("Algo sucedió cuando iba al local");
return;
} else {
pedirCompleto(ingredientes, function notificarPedidoListo(err) {
if (err) {
console.error("Hubo un problema con su completo");
return;
} else {
llamarCliente("1234", function buscarPedido(err) {
if(err) {
console.error("Algo ocurrio cuando llamamos al cliente.");
return;
} else {
recogerPedido();
caminarMesa();
...
}
});
}
});
}
});
Callbacks
Problemas
Inversion-of-control
Callback hell
Difícil de entender
Promises
new Promise(function(resolve, reject) {
if (good) {
resolve(value);
} else {
reject(value);
}
});
Promises
Chaining
const promise = hacerAlgo();
const promise2 = promise.then(successCallback, failureCallback);
// Equivalente a
const promise2 = hacerAlgo().then(successCallback, failureCallback);
Promises
Chaining
hacerAlgo()
.then(function(resultado) {
return hacerAlgoMas(resultado);
})
.then(function(nuevoResultado) {
return hacerUnaTerceraCosa(nuevoResultado);
})
.then(function(resultadoFinal) {
console.log('Resultado final es: ' + resultadoFinal);
})
.catch(failureCallback);
Promises
Error handling
hacerAlgo()
.then(function(resultado) {
return hacerAlgoMas(resultado);
}, function manejarErrorAnterior() {
console.error("Algo sucedio en la promesa anterior");
})
.then(function(nuevoResultado) {
return hacerUnaTerceraCosa(nuevoResultado);
}, function manejarErrorAnterior() {
console.error("Algo sucedio en la promesa anterior");
})
.then(function(resultadoFinal) {
console.log('Resultado final es: ' + resultadoFinal);
}, function manejarErrorAnterior() {
console.error("Algo sucedio en la promesa anterior");
})
.catch(failureCallback);
Promises
irAlLocal(direccion)
.then(function() {
return hacerPedido();
})
.then(function() {
const ingredientes = [...];
return pedirCompleto(ingredientes);
})
.then(function() {
return notificarPedidoListo();
})
.then(function() {
return llamarCliente();
})
.then(function() {
recogerPedido();
caminarMesa();
...
});
Promises
irAlLocal(direccion)
.then(hacerPedido)
.then(function() {
const ingredientes = [...];
return pedirCompleto(ingredientes);
})
.then(notificarPedidoListo)
.then(llamarCliente)
.then(function() {
recogerPedido();
caminarMesa();
...
});
Promises
https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Promise
Promises
Composición
Promise.all([funcion1(), funcion2(), funcion3()])
.then(function ([resultado1, resultado2, resultado3]) {
/* Usar resultado1, resultado2 and resultado3 */
});
//------------
Promise.race([funcion1(), funcion2(), funcion3()])
.then(function (resultado) {
/* Usar resultado */
/* En este caso, resultado será el resultado de
* la promesa que se resuelva primero */
});
Generators
function* generadorNumero(desde = 0, hasta = 100, step = 1) {
let contadorIteracion = 0;
for (let i = desde; i < hasta; i += step) {
contadorIteracion++;
yield i;
}
return contadorIteracion;
}
let gen = generadorNumero();
console.log(gen); // Object [Generator] {} (Iterator)
console.log(gen.next()); // { value: 0, done: false }
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
// ...
console.log(gen.next()); // { value: 100, done: true }
console.log(gen.next()); // { value: undefined, done: true }
Async/await
async function laPrevia() {
try{
const resultado = await hacerAlgo();
const nuevoResultado = await hacerAlgoMas(resultado);
const resultadoFinal = await hacerUnaTerceraCosa(nuevoResultado);
console.log('Resultado final es: ' + resultadoFinal);
} catch(error) {
failureCallback(error);
}
}
hacerAlgo()
.then(function(resultado) {
return hacerAlgoMas(resultado);
})
.then(function(nuevoResultado) {
return hacerUnaTerceraCosa(nuevoResultado);
})
.then(function(resultadoFinal) {
console.log('Resultado final es: ' + resultadoFinal);
})
.catch(failureCallback);
Async/await
async function comerCompletos (donde) {
const ingredientes = [...];
try {
await irAlLocal(donde);
await pedirCompleto(ingredientes);
await notificarPedidoListo();
await llamarCliente();
recogerPedido();
caminarMesa();
} catch (error) {
console.error(error);
}
}
Async/await + Promises
async function laPrevia() {
try{
const resultado = await hacerAlgo();
const nuevoResultado = await hacerAlgoMas(resultado); // Independiente
const segundoNuevoResultado = await hacerOtraCosa(resultado); // Independiente
const resultadoFinal = await hacerUnaTerceraCosa(nuevoResultado, segundoNuevoResultado);
console.log('Resultado final es: ' + resultadoFinal);
} catch(error) {
failureCallback(error);
}
}
async function laPrevia() {
try{
const resultado = await hacerAlgo();
const [nuevoResultado, segundoNuevoResultado] =
await Promise.all([hacerAlgoMas(resultado), hacerOtraCosa(resultado)];
const resultadoFinal = await hacerUnaTerceraCosa(nuevoResultado, segundoNuevoResultado);
console.log('Resultado final es: ' + resultadoFinal);
} catch(error) {
failureCallback(error);
}
}
http://github.com/morph3o
https://medium.com/@pierodivasto
https://www.linkedin.com/in/pierodivasto
https://slides.com/morph3o
https://bit.ly/37tnGFy
Videos:
Libros:
By Piero Divasto
Charla sobre concurrencia en Javascript para la conferencia codeton