I expected the promise handler to log the promise p1
(not the value "A") since console.log
is called with p1
directly. However, it somehow logs "A". How is the promise p1
automatically resolved to "A" without then being called on it ? For example, console.log(p1)
does not output "A" directly as is expected. Is something going on behind the scenes ?
var p1 = new Promise(function(resolve, reject) {
resolve("A");
});
var p2 = new Promise(function(resolve, reject) {
resolve(p1);
});
p2.then(function(v) {
console.log(v)
});
I expected the promise handler to log the promise p1
(not the value "A") since console.log
is called with p1
directly. However, it somehow logs "A". How is the promise p1
automatically resolved to "A" without then being called on it ? For example, console.log(p1)
does not output "A" directly as is expected. Is something going on behind the scenes ?
var p1 = new Promise(function(resolve, reject) {
resolve("A");
});
var p2 = new Promise(function(resolve, reject) {
resolve(p1);
});
p2.then(function(v) {
console.log(v)
});
EDIT: I understand that calling
p1.then((v) => return v))
returns a new promise that is fulfilled with the value v. Unless Im seriously missing something here, the "p1" reference in the second promise constructor should have been passed directly to console.log, resulting in the block
var p2 = new Promise(function(resolve, reject) {
resolve(p1);
});
p2.then(function(v) {
console.log(v)
});
becoming
console.log(p1).
Since console.log is called directly with p1, NOT the result of p1.then(...), p1 should not be resolved into the value "A" in the same way that printing that a another program
var promise = new Promise(function(resolve, reject) {
resolve("B")
})
console.log(promise)
does not result in the string "B".
EDIT2: I had a misconception that the resolve parameter passed to the executor is a wrapper for unfulfilled function, which caused me tons of confusion. Check out Why does the Promise constructor require a function that calls 'resolve' when complete, but 'then' does not - it returns a value instead? for more details.
Share Improve this question edited Sep 30, 2017 at 2:52 kuan asked Sep 29, 2017 at 14:15 kuankuan 4551 gold badge9 silver badges16 bronze badges 5 |3 Answers
Reset to default 18From the MDN documentation:
Promise.resolve(value)
Returns a Promise object that is resolved with the given value. If the value is a thenable (i.e. has a then method), the returned promise will "follow" that thenable, adopting its eventual state; otherwise the returned promise will be fulfilled with the value. Generally, if you don't know if a value is a promise or not, Promise.resolve(value) it instead and work with the return value as a promise.
p1
is thenable, so the return promise follows it.
Resolving a promise to another promise will automatically make it wait for the other promise's result.
This is what makes promises chainable (returning further promises in then()
callbacks).
From MDN Promise().then()
return value:
returns an already fulfilled promise, the promise returned by then gets fulfilled with that promise's value as its value.
If handler function return a Promise()
, it will auto get the value
I have write an article to explain the return value of handler function more detail
If handler function ...
- doesn't return value
var promise = Promise.resolve().then(() => {
// no return;
});
promise.then((value) => {
console.log(promise);
console.log("value =", value);
});
Promise { <state>: "fulfilled", <value>: undefined }
value = undefined
- return value that is not
Promise
var promise = Promise.resolve().then(() => {
return "value";
});
promise.then((value) => {
console.log(promise);
console.log("value =", value);
});
Promise { <state>: "fulfilled", <value>: "value" }
value = value
return Promise.resolve()
var promise = Promise.resolve().then(() => {
return Promise.resolve("value");
});
promise.then((value) => {
console.log(promise);
console.log("value =", value);
});
Promise { <state>: "fulfilled", <value>: "value" }
value = value
return Promise.reject()
var promise = Promise.resolve().then(() => {
return Promise.reject("value");
});
promise.catch((value) => {
console.log(promise);
console.log("value =", value);
});
Promise { <state>: "rejected", <reason>: "value" }
value = value
- return pending
Promise()
var promise = Promise.resolve().then(() => {
return new Promise((resolve, reject) => {
resolve("value");
});
});
promise.then((value) => {
console.log(promise);
console.log("value =", value);
});
Promise { <state>: "fulfilled", <value>: "value" }
value = value
throws "error";
var promise = Promise.resolve().then(() => {
throw "error";
});
promise.catch((value) => {
console.log(promise);
console.log("value =", value);
});
Promise { <state>: "rejected", <reason>: "error" }
value = error
Ref:
Promise()
handler function return value, MDN
resolve
ing and fulfilling. Yes,then
is called behind the scenes:resolve(p1)
becomesp1.then(resolve, reject)
– Bergi Commented Sep 29, 2017 at 14:20resolve
function down to the.then()
stage you may consider nicely packing it by an array (along with some other thingies if needed) and access it further down like.then(v => console.log(v[0]))
. Just a side note. – Redu Commented Sep 29, 2017 at 15:33resolve
's semantics is "take a value and resolve it to aPromise
". This value can be anotherPromise
, of course and expecting that you get a nestedPromise
is plausible. However, the language designers decided to collapse both promises for short-term convenience. Collapsing two promises should be reserved forthen
, though. – user6445533 Commented Mar 14, 2018 at 13:38resolve(promise)
is equivalent to.then(promise)
and both make use of Promise Jobs and Host Operations to Enqueue Jobs, a.k.a. the “job queue”. – Sebastian Simon Commented Nov 29, 2021 at 0:57