admin管理员组文章数量:1420197
As per MDN,
The Promise.all() method takes an iterable of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises. This returned promise will resolve when all of the input's promises have resolved, or if the input iterable contains no promises. It rejects immediately upon any of the input promises rejecting or non-promises throwing an error, and will reject with this first rejection message / error.
Here is a code-snippet which doesn't catch the error as I expected it to as per above definition :-
const promise1 = Promise.resolve(3);
const promise2 = () => {throw new Error('random error')};
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2(), promise3]).then((values) => {
console.log(values);
}).catch(e=>console.log('Error caught',e));
As per MDN,
The Promise.all() method takes an iterable of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises. This returned promise will resolve when all of the input's promises have resolved, or if the input iterable contains no promises. It rejects immediately upon any of the input promises rejecting or non-promises throwing an error, and will reject with this first rejection message / error.
Here is a code-snippet which doesn't catch the error as I expected it to as per above definition :-
const promise1 = Promise.resolve(3);
const promise2 = () => {throw new Error('random error')};
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2(), promise3]).then((values) => {
console.log(values);
}).catch(e=>console.log('Error caught',e));
I know if I convert the promise2()
to return a Promise which rejects then it will work. But what about the non-promises line ? Is it incorrect or am I missing something ?
Update - I got the answer for this behavior. Just curious about what could be possible scenarios for non-promises throwing an error as per the definition ?
Share Improve this question edited Jul 5, 2021 at 8:36 Lakshya Thakur asked Jul 5, 2021 at 8:15 Lakshya ThakurLakshya Thakur 8,3261 gold badge14 silver badges42 bronze badges 2-
It's like doing:
const input = [promise1, promise2(), promise3]; Promise.all(input)
Nothing to do withPromise.all
– adiga Commented Jul 5, 2021 at 8:19 -
3
If you wanted it to behave like you're imaging, just pop an
async
in there:const proimse2 = async () => ...
– TKoL Commented Jul 5, 2021 at 8:21
2 Answers
Reset to default 7Because the error is thrown before you call Promise.all
. It's impossible for Promise.all
to convert that to rejection for you.
You're calling promise2
when building the array, which happens before you pass that array to Promise.all
.
Your code here:
Promise.all([promise1, promise2(), promise3])/*...*/
...is equivalent to the following (other than the variables):
const x0 = promise1;
const x1 = promise2(); // <==== Error is thrown here
const x2 = promise3;
const array = [x0, x1, x2];
Promise.all(array)/*...*/
To make it work as you want, you have several options:
You could make it an async
function, as TKoL pointed out in a ment:
const promise1 = Promise.resolve(3);
const promise2 = async () => {throw new Error('random error')};
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2(), promise3]).then((values) => {
console.log(values);
}).catch(e=>console.log('Error caught',e));
That works because async
functions always return promises (even if you don't use await
) and an error in an async function rejects the promise it returns.
You could make promise2
a thenable so it doesn't throw until then
is called, then Promise.all
would convert that to rejection for you:
const promise1 = Promise.resolve(3);
const promise2 = {
then() {
throw new Error('random error');
}
};
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
// Note no () on promise2 below
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
}).catch(e=>console.log('Error caught',e));
JS first tries to get the arguments correct - then passes the arguments to the function which is called. In your scenario, an error is thrown even before the Promise.all
is called.
To better understand the situation and realize that the Promise interface has nothing to do with your case, see the attached snippet. The PromiseAllTest
function is called with the 3 arguments included in the quesion. But you can see the function is not even called. The error is thrown before it.
const promise1 = Promise.resolve(3);
const promise2 = () => {throw new Error('random error')};
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
try{
console.log('Preparing to call Promise Test');
PromiseAllTest([promise1, promise2(), promise3]);
console.log('Promise Test is called successfully');
}
catch(e) {
console.log('Promise Test is not even called')
}
function PromiseAllTest(promiseArray) {
console.log('Start Processing');
console.log(promiseArray);
console.og('End Processing');
}
本文标签: javascriptWhy Promiseall doesn39t reject when a nonpromise throws an errorStack Overflow
版权声明:本文标题:javascript - Why Promise.all doesn't reject when a non-promise throws an error? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745324817a2653541.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论