Solución:
Promise.all
toma una matriz (o cualquier iterable) de promesas y las cumple cuando todas las cumplen o las rechaza cuando una de ellas rechaza. Creo que es más fácil de entender si lo implementamos y entendemos por qué lo necesitamos.
Un caso de uso común podría ser esperar a que se cargue la ventana y que el servidor devuelva datos para ejecutar algún código:
// a function that returns a promise for when the document is ready.
function windowReady(){
return new Promise(function(resolve){
window.addEventListener('DOMContentLoaded', resolve);
});
}
// function that returns a promise for some data
function getData(){
return fetch("https://foroayuda.es/").then(function(r){ return r.json() });
}
Ahora, queremos que ambos ejecuten al mismo tiempo y luego obtén el resultado. Aquí hay dos elementos, pero fácilmente podría haber 5 cosas por las que esperar, o 100. Así que usamos Promise.all
:
Promise.all([windowReady(), getData()]).then(function(results){
// results[1] is the data, it's all in an array.
});
Veamos cómo podemos implementarlo:
function all(iterable){ // take an iterable
// `all` returns a promise.
return new Promise(function(resolve, reject){
let counter = 0; // start with 0 things to wait for
let results = [], i;
for(let p of iterable){
let current = i;
counter++; // increase the counter
Promise.resolve(p).then(function(res){ // treat p as a promise, when it is ready:
results[i] = res; // keep the current result
if(counter === 0) resolve(results) // we're done
}, reject); // we reject on ANY error
i++; // progress counter for results array
}
});
}
O, en aún más ES6ness:
let all = iterable => new Promise((resolve, reject) => {
let arr = [...iterable], c = arr.length, results = [];
arr.map(Promise.resolve, Promise).
map((p, i) => p.then(v => {
r[i] = v;
if(--c === 0) resolve(r);
} , reject));
});
Tu get
la función devuelve un Promise
. Simplemente está pasando una referencia al get
función. Tienes que pasar una serie de Promises
Promise.all([get("one.jpg")]).then(...);
TLDR:
Promise.all
es un método de Javascript que toma un iterable (p. ej. Array
) de promesas como argumento y devuelve una sola promesa cuando todos las promesas en el argumento iterable se han resuelto (o cuando el argumento iterable no contiene promesas). Se resuelve con una matriz de los valores resueltos y se rechaza con un solo valor de la primera Promesa rechazada.
Ejemplo:
var promise1 = Promise.resolve(5);
var promise2 = Math.random() > 0.5? 1 : Promise.reject(1); // either resolves or rejects
var promise3 = new Promise((resolve, reject) => {
setTimeout(() => resolve('foo'), 1000);
});
Promise.all([promise1, promise2, promise3]).then((val) => {
console.log(val);
}).catch((val) => {
console.log(val);
});
En el ejemplo anterior, 3 promesas se pasan al Promise.all
funcionar como una matriz. Las promesas 1 y 3 siempre se resuelven. La promesa 2 se resuelve o rechaza según el generador de números aleatorios. Este método Promise.all luego devuelve una Promesa resuelta o rechazada basada en el generador Nr aleatorio.
Entonces el then()
método y el catch()
se puede llamar al método en esta promesa que se devuelve de Promise.all
. los then()
El método obtiene una matriz de todos los valores resueltos, [5, 1, 'foo']
en este caso. los catch()
El método obtiene el valor de la primera Promesa rechazada, 1
en este ejemplo.
Cuándo usar:
Este método es muy útil cuando desea ejecutar múltiple operaciones asíncronas y necesita algo con los resultados después de las operaciones asíncronas. Cuando usas Promise.all
todas las promesas se pueden procesar al mismo tiempo sin dejar de operar con todos los datos entrantes.
Por ejemplo, cuando necesitamos obtener información usando múltiples solicitudes AJAX y combinar los datos en algo útil. Es fundamental esperar a que todos los datos estén disponibles, de lo contrario, intentaríamos combinar los datos no existentes, lo que provocaría problemas.