Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With a Promise, why do browsers return a reject twice but not a resolve twice?

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: enter image description here

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

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...

like image 616
John Avatar asked Oct 08 '19 14:10

John


People also ask

Can you resolve a promise twice?

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.

How many times can a promise be rejected?

')); }); 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.

Does Promise return After resolve?

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.

What happens if neither resolve nor reject is called within a promise?

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.


1 Answers

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.

like image 79
T.J. Crowder Avatar answered Sep 19 '22 08:09

T.J. Crowder