I have the following code:
function myPromiseFunc() {
return new Promise((resolve) => {
resolve(Promise.resolve(123));
});
}
As we know Promise.resolve method resolves Promise with a plain value immediately.
So Promise.resolve(123) -> Promise<fulfilled>
But:
console.log(myPromiseFunc());
will return Promise with status pending. Why? Is resolve function passed to executor async? Cause this:
setTimeout(console.log, 0, res);
will return Promise<fulfilled>.
I know Promises use microtasks but it's supposed to use only for handlers.
Promises/A+ says:
[[Resolve]](promise, x) -> If/when x is a promise and fulfilled, fulfill promise with the same value.
By the way. This snipped will return Promise<fulfilled>:
function myPromiseFunc() {
return new Promise((resolve) => {
resolve(123);
});
}
So it looks like resolve is async only when Promise passed as a value.
Please, help to understand. Thank you!
According to the specification of the resolve function passed to the executor in new Promise((resolve, reject) => ...):
When a promise resolve function is called with argument resolution, the following steps are taken:
F be the active function object.F has a [[Promise]] internal slot whose value is an Object.promise be F.[[Promise]].alreadyResolved be F.[[AlreadyResolved]].alreadyResolved.[[Value]] is true, return undefined.alreadyResolved.[[Value]] to true.SameValue(resolution, promise) is true, then
selfResolutionError be a newly created TypeError object.RejectPromise(promise, selfResolutionError).Type(resolution) is not Object, then
FulfillPromise(promise, resolution).then be Get(resolution, "then").then is an abrupt completion, then
RejectPromise(promise, then.[[Value]]).thenAction be then.[[Value]].IsCallable(thenAction) is false, then
FulfillPromise(promise, resolution).thenJobCallback be HostMakeJobCallback(thenAction).job be NewPromiseResolveThenableJob(promise, resolution, thenJobCallback).HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]]).undefined.Lots of technical jargon, but the most important bits for your question is that resolution is the value you passed to it. If it's (roughly) a non-Promise, you'll end up either in 8.1 (for non-objects) or 12.1 (for non-callable objects), which will all immediately fulfill the promise. If you passed a value with a then function (e.g. a Promise), it'll do all the steps starting from 13 where it basically queues up the .then and follows the whole "my fulfillment depends on another Promise's fulfillment".