I understand Promises to exist in one of three states: A Promise can either be pending (unresolved), fulfilled (resolved successfully) or <
We can resolve a promise with another promise.
To answer your second question first: Yes, there is an instance in which the value we pass to resolve might result in the Promise being rejected, and that is if we pass it a rejected promise, e.g. Promise.reject()
.
To answer your first question of isn't resolve and fulfill the same: Consider the case where the value we pass to resolve is a pending promise. In this case our own promise will not settle immediately as a result:
a().then(() => new Promise(setTimeout)).catch(e => console.error(e));
In this case we say a promise is "resolved to" another promise, and it remains pending.
This is all happening behind our backs inside then
, so it might be easier to look at a vintage case where a
does not support promises (takes callbacks), and we don't flatten things correctly:
// Old times and unflattened for exposition:
new Promise((resolve, reject) => a(function(result) {
resolve(new Promise(setTimeout));
}, reject))
.then(() => console.log("after setTimeout"))
.catch(e => console.error(e));
Here we see more clearly that resolve is called with another promise. Importantly, the resolved promise does not fulfill and fire the "after setTimeout"
message until the second promise resolves (with a non-promise undefined
value from setTimeout
), at which point both promises become fulfilled (in other words: these two promises just formed a resolve chain).
This is key to understanding that resolved is different from fulfilled or even settled (fulfilled or rejected, not pending).
From States and Fates:
The fate refers to whether the fate of a single promise has been reached, and does not correspond directly to any state transition, because of resolve chains.