It is asserted the ECMAScript promises is a Promises/A+ implementation, so they have no contradictions. However, I encountered a behaviour of ecma promises which allegedly is out of line with the Promises/A+.
When we call promise1.then(onFulfilled, onRejected)
to listen to the promise1
's output, we get as a return value another promise (promise2
). When the needed callback (onFulfilled/onRejected
) was executed and it, in turn, returned some value x
, the spec prescribes to resolve it with the defined [[Resolve(promise2, x)]]
function. Let's suppose x
happened to be a promise itself (x === promise3
), then the steps must be taken is the following:
- If
x
is a promise, adopt its state:- If
x
is pending,promise2
must remain pending untilx
is fulfilled or rejected.- If/when
x
is fulfilled, fulfillpromise2
with the same value.- If/when
x
is rejected, rejectpromise2
with the same reason.
I wonder what if x
is finally fulfilled with yet another promise (promise4
) (there are not anything in the way of it, are there?). It can be concluded from the spec excerpt that promise2
must be fulfilled with promise4
too. But it is seemingly not so in the ECMAScript world:
let promise4 = new Promise((resolve) => { resolve(4) })
let promise3 = new Promise((resolve) => {
resolve(promise4);
});
let promise1 = new Promise((resolve) => {
resolve(1);
});
let promise2 = promise1.then((val) => { return promise3 });
promise2.then(val => console.log(val)); // output: 4
In the other words, promise2
is fulfilled with the promise4
's value. This behaviour is like one that is defined in the spec for other thenable
objects. So don't ECMAScript promises carry out expected type checking and just check whether x
has then
method?