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...
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.
')); }); An important point to note: A Promise executor should call only one resolve or one reject . Once one state is changed (pending => fulfilled or pending => rejected), that's all.
The Promise. resolve() method "resolves" a given value to a Promise . If the value is a promise, that promise is returned; if the value is a thenable, Promise. resolve() will call the then() method with two callbacks it prepared; otherwise the returned promise will be fulfilled with the value.
So failing to resolve or reject a promise just fails to ever change the state from "pending" to anything else. This doesn't cause any fundamental problem in Javascript because a promise is just a regular Javascript object.
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.
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