简体   繁体   中英

How can calling a catch() method "try catch" the exception of a promise?

In other words, we usually cannot "try catch" an exception simply by calling another method.

But we can handle the exception of a promise by

promise
  .then()
  .catch();

or

promise
  .then(fulfillmentHandler, rejectionHandler);

If the promise.then() in the first case threw an exception, how can invoking catch() , which is a method, on that promise handle the exception that happened previously?

We usually have to handle an exception by wrapping it using

try {
  // doSomething
} catch (err) {
  // handle the error
}

so if the exception happened for the promise that the then() returned, doesn't the code have to handle the exception when promise.then() has run? Simply invoking a method on an object usually would not be able to handle its exception (in this case invoking catch() on the promise that then() returned), because there is no such wrapping?

The best you can do is look up some promise polyfill.

Any function passed to promise, in the constructor or in .then a callback is internally wrapped in try-catch, and if this function throws, it will trigger next .catch (or throw unhandled promise rejection error).

Wrapping promise in try-catch won't, however, catch unhandled rejections as they are somewhat special. To catch them you have to use this: ( reference )

window.addEventListener('unhandledrejection', function(event) {
    console.error(`Unhandled rejection (promise: ${event.promise}, reason: ${event.reason}).`);
});

if the exception happened for the promise that the then() returned, doesn't the code have to handle the exception when promise.then() has run?

The exception that would happen in the Promise returned by then would not have happened yet, it will only happen in the micro-task of that Promise, after the main task is done.

 Promise.resolve() .then( callback ) // still synchronously in the main task, no error yet .catch( console.error ); console.log( "done with main task" ); // this will only get executed in a micro-task, when the main task is done function callback() { console.log( "will now throw" ); throw new Error( "not good" ); }

So the Promise objects returned by these .then() and .catch() will be able to append the callbacks just fine, and nothing in the main task will throw.



The only thing that might be confusing is the Promise constructor, which will wrap exceptions synchronously:

 const promise = new Promise( () => { console.log( "will now throw" ); throw new Error( "not good" ); } ); console.log( "yet here we are fine" );

But that's not really different than with Events:

 addEventListener( 'test', e => { console.log( "will now throw" ); throw new Error( "not good" ); } ); dispatchEvent( new Event( "test" ) ); console.log( "Yet we are fine" );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM