Promesas
Las promesas representa un resultado eventual de una operación asincrónica, la primera manera de interactuar con un una promesa o promise es a través del método then el cual registra el callback que recivirá la respuesta o la razón por la cual la promesa no a podido ser cumplida.
Estados
Las promesas pueden estar en 3 estados pending, fulfilled y rejected

Pending
Cuando una promesa no se haya terminado aún pero aún no ha sido rechazada. (a la espera), y la respuesta podrá ser fulfilled o rejected.
Fulfilled
Cuando la respuesta ha sido devuelta y procesada correctamente, no podrá cambiar de estado y el valor no debe cambiar (debido a la promesa, por otro procesamiento sí).
Rejected
Cuando ha ocurrido un error en la promesa, el estado de la transición no debe cambiar y debe tener una razón por la cual a sucedido el error la cual no debe cambiar. para obtener los resultados rejected utilizamos la palabra reservada catch
Cuando digo que algo no debe cambiar quiero decir que deberá ser comprobado con
===.
más información sobre promesas
Ejemplos
Ejemplo de llamada a
then
const promise = new Promise((resolve, reject) => {
resolve(123);
});
promise.then((res) => {
console.log('I get called:', res === 123); // Devuelve: true
});
promise.catch((err) => {
// Nuca es utilizado
});
Ejemplo de llamada a
catch
const promise = new Promise((resolve, reject) => {
reject(new Error("Algo malo a pasado"));
});
promise.then((res) => {
// This is never called
});
promise.catch((err) => {
console.log('Tengo una llamada: ', err.message); // Tengo una llamada: 'Algo malo a pasado'
});
Cadenas de promesas o Chain-ability of Promises
Una cadena de promesas es una manera muy útil de realizar peticiones asíncronas.
Sí una promesa hace un return la cadena hace la siguiente petición al then
Promise.resolve(123)
.then((res) => {
console.log(res); // 123
return 456;
})
.then((res) => {
console.log(res); // 456
return Promise.resolve(123);
})
.then((res) => {
console.log(res); // 123 : Notice that this `this` is called with the resolved value
return Promise.resolve(123);
})
Puedes manejar los esrrores añadiendole un método catch a la cadena.
Promise.reject(new Error('something bad happened'))
.then((res) => {
console.log(res); // not called
return 456;
})
.then((res) => {
console.log(res); // not called
return Promise.resolve(123);
})
.then((res) => {
console.log(res); // not called
return Promise.resolve(123);
})
.catch((err) => {
console.log(err.message); // something bad happened
});
También se puede hacer que un método catch continue con la cadena de promesas, de la siguiente manera:
Promise.reject(new Error('something bad happened'))
.then((res) => {
console.log(res); // not called
return 456;
})
.catch((err) => {
console.log(err.message); // something bad happened
return Promise.resolve(123);
})
.then((res) => {
console.log(res); // 123
})
Cualquier error ocurrido en un then llamará al método catch. Ej.:
Promise.resolve(123)
.then((res) => {
throw new Error('something bad happened')
return 456;
})
.then((res) => {
console.log(res); // never called
return Promise.resolve(789);
})
.catch((err) => {
console.log(err.message); // something bad happened
})
El hecho de que el primer then al dar un error se salte el siguiente then siendo una llamada asincrónica, nos provee con un nuevo paradicma el cual nos permite capturar mejor las excepciones asíncronas.
También es posible que algunas funciones puedan devolver promesas como por ejemplo:
function iReturnPromiseAfter1Second():Promise<string> {
return new Promise((resolve)=>{
setTimeout(()=>resolve("Hello world!"), 1000);
});
}
Promise.resolve(123)
.then((res)=>{
// res is inferred to be of type `number`
return iReturnPromiseAfter1Second();
})
.then((res) => {
// res is inferred to be of type `string`
console.log(res); // Hello world!
});
En el siguiente ejemplo veremos como se hace la carga de un JSON de forma asíncrona:
// good json file
loadJSONAsync('good.json')
.then(function (val) { console.log(val); })
.catch(function (err) {
console.log('good.json error', err.message); // never called
})
// non-existent json file
.then(function () {
return loadJSONAsync('absent.json');
})
.then(function (val) { console.log(val); }) // never called
.catch(function (err) {
console.log('absent.json error', err.message);
})
// invalid json file
.then(function () {
return loadJSONAsync('bad.json');
})
.then(function (val) { console.log(val); }) // never called
.catch(function (err) {
console.log('bad.json error', err.message);
});
Promesas en paralelo
Como habréis observado previamente, hasta ahora todos los ejemplos que hemos visto heran peticiones en serie pero que sentido tiene eso si lo que queremos es una carga asincrónica de la información, pues no mucha es por eso que ahora veremos un ejemplo de como serían las peticiones en paralelo.
TypeScript
//-------- main.ts ---------
// Una función asincróna simulando la petición desde el servidor
function loadItem(id: number): Promise<{id: number}> {
return new Promise((resolve)=>{
console.log('loading item', id);
setTimeout(() => { // simulate a server delay
resolve({ id: id });
}, 1000);
});
}
// Cadena (serie)
let item1, item2;
loadItem(1)
.then((res) => {
item1 = res;
return loadItem(2);
})
.then((res) => {
item2 = res;
console.log('done');
}); // overall time will be around 2s
// Paralelo
Promise.all([loadItem(1),loadItem(2)])
.then((res) => {
[item1,item2] = res;
console.log('done')
}); // overall time will be around 1s
Javascript
//-------- main.js ---------
// Una función asincróna simulando la petición desde el servidor
function loadItem(id) {
return new Promise((resolve) => {
console.log('loading item', id);
setTimeout(() => {
resolve({ id: id });
}, 1000);
});
}
// Cadena (serie)
let item1, item2;
loadItem(1)
.then((res) => {
item1 = res;
return loadItem(2);
})
.then((res) => {
item2 = res;
console.log('done');
}); // overall time will be around 2s
// Paralelo
Promise.all([loadItem(1), loadItem(2)])
.then((res) => {
[item1, item2] = res;
console.log('done');
}); // overall time will be around 1s
Para poder testear esto ejecutaremos el javascript en nuestro serviudor node
node main.js