Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the reason to allow multiple resolve/reject in ES6 Promise

I found that is possible (in ES6 promises, while Promise object is created) to use multiple resolve/reject which will affect PromiseStatus only once but not affect execution flow.

var p = new Promise(function(resolve, reject) { 
    setTimeout(function(){
        resolve(1);
        console.log('Resolve 1');
    }, 50);
    setTimeout(function(){
        resolve(2);
        console.log('Resolve 2');
    }, 100);
});

setTimeout(function(){
        console.log('Status #1:', p);
    }, 10);
setTimeout(function(){
        console.log('Status #2:', p);
    }, 60);
setTimeout(function(){
        console.log('Status #3:', p);
    }, 110);

p.then(function(x){
    console.log('Value after:', x)
})

In then() functions first resolve/reject will affect execution flow. So my question is - why it works like this (feature/bug)?

P.S. My env is Node 4.1

P.P.S. My output:

Status #1: Promise { <pending> }
Resolve 1
Value after: 1
Status #2: Promise { 1 }
Resolve 2
Status #3: Promise { 1 }
like image 845
Michael Plakhov Avatar asked Dec 23 '15 12:12

Michael Plakhov


People also ask

What happens if multiple resolve or reject is called within a promise?

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.

What is resolve reject in promise?

A promise that is either resolved or rejected is called “settled”, as opposed to an initially “pending” promise. There can be only a single result or an error. The executor should call only one resolve or one reject . Any state change is final.

What happens if promise is not resolved or rejected?

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.


2 Answers

Well, I want to talk about the why. Promises are proxies for single values so running handlers a second time or changing the value doesn't make sense. You can't change the number 5 to be the number 3 for instance.

Let's talk about what alternatives we have for resolve being called a second time. Let's say we didn't want to allow it - how would we signal that?

Normally, we'd throw - the problem is - it would be caught nowhere since throws in the promise constructor get converted to rejections. .catch handlers would not run because the promise already resolved.

So we can't really throw as that'd mean an exception you can't handle (a very bad place to be). We can't run handlers twice (that would break the model). So our only choice left is to allow it.

like image 69
Benjamin Gruenbaum Avatar answered Sep 28 '22 17:09

Benjamin Gruenbaum


As per the ECMAScript 2015 Specification, sections Promise Reject Functions and Promise Resolve Functions say that,

  1. If alreadyResolved.[[value]] is true, return undefined.

So, if the current promise object is already resolved, then neither resolve, nor reject do anything to the Promise object. It actually means that, only the first resolve/reject matter.

like image 39
thefourtheye Avatar answered Sep 28 '22 17:09

thefourtheye