最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Passing another promise to a promise handler - Stack Overflow

programmeradmin1浏览0评论

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
  • 2 That's the difference between resolveing and fulfilling. Yes, then is called behind the scenes: resolve(p1) becomes p1.then(resolve, reject) – Bergi Commented Sep 29, 2017 at 14:20
  • @Bergi I believe that your comment here is the answer I am looking for. More explanation as to how resolve(p1) becomes p1.then(resolve, reject) in an answer would be really helpful! – kuan Commented Sep 29, 2017 at 14:45
  • If you want to move a promise object through the resolve 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:33
  • Please note that your original expectation is reasonable, because resolve's semantics is "take a value and resolve it to a Promise". This value can be another Promise, of course and expecting that you get a nested Promise is plausible. However, the language designers decided to collapse both promises for short-term convenience. Collapsing two promises should be reserved for then, though. – user6445533 Commented Mar 14, 2018 at 13:38
  • Relevant bits of the specification: The Promise Constructor and Promise Resolve Functions. resolve(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
Add a comment  | 

3 Answers 3

Reset to default 18

From 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

发布评论

评论列表(0)

  1. 暂无评论