One of the exercises in Chapter 17 of the book Eloquent Javascript is to implement the Promise.all() method, I came up with this implementation (which doesn't work):
function all(promises) {
return new Promise(function(success, fail) {
var successArr = new Array(promises.length);
if (promises.length == 0)
success(successArr);
var pending = promises.length;
for (var i = 0; i < promises.length; i++) {
promises[i].then(function(result) {
successArr[i] = result;
pending -= 1;
if (pending == 0)
success(successArr);
}, function(error) {
fail(error);
});
}
});
}
// Testing
function soon(val) {
return new Promise(function(success) {
setTimeout(function() { success(val); },
Math.random() * 500);
});
}
all([soon(1), soon(2), soon(3)]).then(function(array) {
console.log("This should be [1, 2, 3]:", array);
});
// => [undefined, undefined, undefined, 3]
Interestingly, the author's solution is similar apart from the use of forEach to iterate over the promises array instead of the for loop in my case:
function all(promises) {
return new Promise(function(success, fail) {
var successArr = new Array(promises.length);
if (promises.length == 0)
success(successArr);
var pending = promises.length;
promises.forEach(function(promise, i) {
promise.then(function(result) {
successArr[i] = result;
pending -= 1;
if (pending == 0)
success(successArr);
}, function(error) {
fail(error);
});
});
});
}
// Testing
function soon(val) {
return new Promise(function(success) {
setTimeout(function() { success(val); },
Math.random() * 500);
});
}
all([soon(1), soon(2), soon(3)]).then(function(array) {
console.log("This should be [1, 2, 3]:", array);
});
// => [1, 2, 3]
Why does the use forEach makes all the difference here?, I'm guessing it's something related to the scope created by the anonymous function passed to forEach, but I can't quite figure how that works.
Promise.all waits for all fulfillments (or the first rejection).
No. It is not safe to resolve/reject promise multiple times. It is basically a bug, that is hard to catch, becasue it can be not always reproducible.
As you can see, Promise. all executes code concurrently, but what is parallel execution? JavaScript is single-threaded and can only perform a single chunk of work at a time, so parallel execution is not possible with JavaScript, except for some circumstances such as web workers.
In this approach, we will use Promise. allSettled() which will be executed in a quite similar manner as Promise. all() method executed by taking promises as input in the single array and executing them sequentially.
I just figured it out, it's the i
variable, because we're on a for loop, it changes before the promise get a chance to resolve but on the forEach version the i variable is properly scoped so each iteration has it's own i
variable
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With