In this article, we will talk about why Promise.all() method does not get rejected when one of the non-input promises throws an error, and in which cases the Promise.all() does get rejected.
Promise.all() is a method that returns a promise. It takes an array of promises as its argument and returns a single promise, which gets rejected even if one of the promises (passed as an argument) gets rejected.
Example 1:
Javascript
<script> const promise1 = Promise.resolve( "Hello world" ); const promise2 = Promise.resolve( "GFG" ); const promise3 = Promise.resolve( "success" ) // when all the promises are resolved, // Promise.all() gets resolved as well Promise.all([promise1, promise2, promise3]).then(res => { console.log(res); }); </script> |
Output:
["Hello world", "GFG", "success"]
Example 2:
Javascript
<script> const promise1 = Promise.resolve( "Hello world" ); const promise2 = Promise.resolve( "GFG" ); const promise3 = Promise.reject( "promise rejected" ) // If any one (or more) of the promises // get rejected, the Promise.all() // gets rejected too with the rejection // message of the first // rejected promise it encountered Promise.all([promise1, promise2, promise3]). catch (error => { // output - "Promise rejected" console.log( "Promise rejected" ); }); </script> |
Output:
Promise rejected
Now, let’s try to reproduce a case when Promise.all() does not get rejected when one of the array elements (passed as an argument to Promise.all()) throws an error.
Javascript
<script> const promise1 = Promise.resolve( "Hello world" ); const promise2 = () => { throw new Error( "error!" ); }; const promise3 = Promise.resolve( "GFG" ); Promise.all([promise1, promise2(), promise3]) .then(res => { console.log(res); }) . catch (error => console.log( "Promise rejected!" )); </script> |
Output:
As we can see in the output above, even though the promise2 function throws an error, the Promise.all() method does not get rejected, and the browser throws an unhandled error. At first glance, this might seem an unusual case, but on careful analysis, one can observe the reason why Promise.all() does not get rejected here because the promise2 function does not actually return a promise, and it throws an error even before Promise.all() is called (if you see the Promise.all() argument, promise2 is called inside the argument itself, thus causing it to throw an error before Promise.all() itself is called).
Now, to solve this problem, let’s look at some of the below approaches –
Approach 1: Converting non-promise array elements into promise objects
In this approach, we will make sure that the array, is passed to the Promise.all() method, has all elements as promise objects. This way, we can be sure that none of the array elements returns a response before the Promise.all() is executed.
Example:
Javascript
<script> const promise1 = Promise.resolve( "Hello world" ); const promise2 = async () => { throw new Error( "error!" ); }; const promise3 = Promise.resolve( "GFG" ); Promise.all([promise1, promise2(), promise3]) .then(res => { console.log(res); }) . catch (error => console.log( "Promise rejected!" )); </script> |
In the code above, we used async in the promise2 function as we know that all async functions return a promise as a response.
Output:
Approach 2: Creating a then() method inside the non-promise array element
In this approach, we will create a then() method inside the non-promise array element and throw the error inside the method. This is to ensure that the error is not thrown until the then() method is called, and then when the error is thrown, the Promise.all() gets rejected.
Example:
Javascript
<script> const promise1 = Promise.resolve( "Hello world" ); const promise2 = { // Create a then() method which is // called in Promise.all() then() { throw new Error( "error!" ); } }; const promise3 = Promise.resolve( "GFG" ); Promise.all([promise1, promise2, promise3]) .then(res => { console.log(res); }) . catch (error => console.log( "Promise rejected!" )); </script> |
Output: