With a Promise, why do browsers return a reject tw

2020-08-25 04:57发布

问题:

I'm having trouble understanding javaScript promises. I wrote the following code:

var p = new Promise(function(resolve,reject){

    reject(Error("hello world"));
});

setTimeout(()=>p.catch(e=>console.log(e)),5000);

I immediately see this in my Chrome developer console:

But after I wait 5 seconds, the message automatically changes to black like this image:

I've never seen this behaviour before between my javaScript code and a developer console, where my javaScript code can "modify existing content" in the developer console.

So I decided to see if the same situation occurs with resolve by writing this code:

var p = new Promise(function(resolve,reject){

    resolve("hello world");
});

setTimeout(()=>p.then(e=>console.log(e)),5000);

But in this situation, my developer console doesn't show anything until 5 seconds later, to which it then prints hello world.

Why are the resolve and reject treated so differently in terms of when they are invoked?


EXTRA

I also wrote this code:

var p = new Promise(function(resolve,reject){

    reject(Error("hello world"));
});

setTimeout(()=>p.catch(e=>console.log("errors",e)),5000);
setTimeout(()=>p.catch(e=>console.log("errors 2",e)),6000);
setTimeout(()=>p.catch(null),7000);

This causes several outputs to the developer console. Red error at time 0, red changes to black at time 5 seconds with the text errors hello world, then a new error message at time 6 seconds errors 2 hello world, then a red error message at time 7 seconds. Now I'm very confused on how many times a reject actually gets invoked....I'm lost...

回答1:

Wow, that's really cool. I'd never seen the console do that before. (It has other forms of dynamic behavior, though, so...) Here's what's going on:

In the first case, code execution of everything outside your setTimeout callback's code completes and the execution stack returns so that only "platform code" (as the Promises/A+ spec calls it) is running, not userland JavaScript code (for the moment). At that point, the promise is rejected and nothing has handled the rejection, so it's an unhandled rejection and devtools reports it to you as such.

Then, five seconds later, your callback runs and attaches a rejection handler. At this point, the rejection is no longer unhandled. Apparently, Chrome/V8/devtools work together to remove the unhandled rejection warning from the console. What you see appear instead is what you output in your rejection handler via console.log. If you attached the rejection handler sooner, you wouldn't get that unhandled rejection error.

This doesn't happen with fulfillment because not handling fulfillment isn't an error condition. Not handling rejection is.