The Promise.all(arr).then
callback is executed before the array is fulfilled, so it doesn’t catch its elements. How can I do this properly?
var arr = [];
for (var i = 0; i < 2; i++) {
arr.push((function() {
new Promise(function(resolve, reject) {
setTimeout(function() {
console.log("Resolved!");
resolve();
}, 3000);
});
})());
}
Promise.all(arr).then(function() {
console.log("Done");
});
My expect result is:
Resolved!
Resolved!
Done
But real result is:
Done
Resolved!
Resolved!
The code above is just an example. I changed the structure like below and the code no longer has a problem, but I should use a for
loop and push
because of my application structure.
var p1 = new Promise(function(resolve, reject) {
setTimeout(function() {
console.log("Resolved #1");
resolve();
}, 1000);
});
var p2 = new Promise(function(resolve, reject) {
setTimeout(function() {
console.log("Resolved #2");
resolve();
}, 2000);
});
var arr = [p1, p2];
Promise.all(arr).then(function() {
console.log("Done");
});
As georg said, you're just not putting the promises in arr
, because you never return anything from the anonymous function you've wrapped around new Promise
. That function is also completely unnecessary, so:
var arr = [];
for (var i = 0; i < 2; i++) {
arr.push(new Promise(function(resolve, reject) {
setTimeout(function() {
log('resolved !');
resolve();
}, 500);
}));
}
Promise.all(arr).then(function() {
log("Done");
});
function log(msg) {
var p = document.createElement('p');
p.appendChild(document.createTextNode(msg));
document.body.appendChild(p);
}
If the function is there so you can capture the then-current value of i
, just ensure you return the promise:
var arr = [];
for (var i = 0; i < 2; i++) {
arr.push(function(index) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
log('resolved with ' + index + ' !');
resolve(index);
}, 500);
});
}(i));
}
Promise.all(arr).then(function() {
log("Done");
});
function log(msg) {
var p = document.createElement('p');
p.appendChild(document.createTextNode(msg));
document.body.appendChild(p);
}