By spirytus


2014-12-31 02:08:30 8 Comments

What is the difference between:

new Promise(function(res, rej) {
    res("aaa");
  })
  .then(function(result) {
    return "bbb";
  })
  .then(function(result) {
    console.log(result);
  });

and this:

new Promise(function(res, rej) {
    res("aaa");
  })
  .then(function(result) {
    return Promise.resolve("bbb");
  })
  .then(function(result) {
    console.log(result);
  });

I'm asking as I'm getting different behaviour Using Angular and $http service with chaining .then(). A bit too much code hence first the example above.

5 comments

@vkarpov15 2020-01-22 16:30:18

The only difference is that you're creating an unnecessary promise when you do return Promise.resolve("bbb"). Returning a promise from an onFulfilled() handler kicks off promise resolution. That's how promise chaining works.

@Arian Acosta 2017-11-07 22:00:59

In simple terms, inside a then handler function:

A) When x is a value (number, string, etc):

  1. return x is equivalent to return Promise.resolve(x)
  2. throw x is equivalent to return Promise.reject(x)

B) When x is a Promise that is already settled (not pending anymore):

  1. return x is equivalent to return Promise.resolve(x), if the Promise was already resolved.
  2. return x is equivalent to return Promise.reject(x), if the Promise was already rejected.

C) When x is a Promise that is pending:

  1. return x will return a pending Promise, and it will be evaluated on the subsequent then.

Read more on this topic on the Promise.prototype.then() docs.

@Lancer.Yan 2020-07-04 09:56:40

【B) 2.】should be "throw x" ?

@Arian Acosta 2020-07-06 13:49:24

@Lancer.Yan Not really, what B is indicating is that the behavior of return changes depending on the settled value of the Promise. When writing the code you don't really know if it will resolve or reject. Of course, you can have a try-catch to handle rejects and then re-throw, but that's a different scenario.

@JLRishe 2014-12-31 05:21:45

Both of your examples should behave pretty much the same.

A value returned inside a then() handler becomes the resolution value of the promise returned from that then(). If the value returned inside the .then is a promise, the promise returned by then() will "adopt the state" of that promise and resolve/reject just as the returned promise does.

In your first example, you return "bbb" in the first then() handler, so "bbb" is passed into the next then() handler.

In your second example, you return a promise that is immediately resolved with the value "bbb", so "bbb" is passed into the next then() handler. (The Promise.resolve() here is extraneous).

The outcome is the same.

If you can show us an example that actually exhibits different behavior, we can tell you why that is happening.

@FabianTe 2018-05-29 12:06:51

Nice answer! What about Promise.resolve(); vs return;?

@JLRishe 2018-05-29 19:42:10

@FabianTe Those also would have the same effect, except with undefined instead of "bbb".

@Hrishi 2014-12-31 05:31:43

The rule is, if the function that is in the then handler returns a value, the promise resolves/rejects with that value, and if the function returns a promise, what happens is, the next then clause will be the then clause of the promise the function returned, so, in this case, the first example falls through the normal sequence of the thens and prints out values as one might expect, in the second example, the promise object that gets returned when you do Promise.resolve("bbb")'s then is the then that gets invoked when chaining(for all intents and purposes). The way it actually works is described below in more detail.

Quoting from the Promises/A+ spec:

The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as [[Resolve]](promise, x). If x is a thenable, it attempts to make promise adopt the state of x, under the assumption that x behaves at least somewhat like a promise. Otherwise, it fulfills promise with the value x.

This treatment of thenables allows promise implementations to interoperate, as long as they expose a Promises/A+-compliant then method. It also allows Promises/A+ implementations to “assimilate” nonconformant implementations with reasonable then methods.

The key thing to notice here is this line:

if x is a promise, adopt its state [3.4]

link: https://promisesaplus.com/#point-49

@user663031 2014-12-31 06:32:36

"Adopt its state" is a concise and useful way to express the behavior when a then handler returns a promise. +1 for the spec reference.

@Benjamin Gruenbaum 2014-12-31 07:20:29

Actually - the relevant part of the spec here is the fact that [[Resolve]] is called both on thenables and values so essentially it wraps a value with the promise so return "aaa" is the same as return Promise.resolve("aaa") and return Promise.resolve("aaa") is the same as return Promise.resolve(Promise.resolve("aaa")) - since resolve is idempotent calling it on a value more than once has the same result.

@CSnerd 2015-12-06 19:10:24

@Benjamin Gruenbaum does it mean that return "aaa" and return Promise.resolve("aaa") are interchangeable in thenables in any cases?

@Benjamin Gruenbaum 2015-12-06 20:01:58

Yes, that's exactly what it means.

@Benjamin Gruenbaum 2014-12-31 07:37:13

You already got a good formal answer. I figured I should add a short one.

The following things are identical with Promises/A+ promises:

  • Calling Promise.resolve (In your Angular case that's $q.when)
  • Calling the promise constructor and resolving in its resolver. In your case that's new $q.
  • Returning a value from a then callback.
  • Calling Promise.all on an array with a value and then extract that value.

So the following are all identical for a promise or plain value X:

Promise.resolve(x);
new Promise(function(resolve, reject){ resolve(x); });
Promise.resolve().then(function(){ return x; });
Promise.all([x]).then(function(arr){ return arr[0]; });

And it's no surprise, the promises specification is based on the Promise Resolution Procedure which enables easy interoperation between libraries (like $q and native promises) and makes your life overall easier. Whenever a promise resolution might occur a resolution occurs creating overall consistency.

@Sampgun 2020-02-13 10:43:47

may I ask what's the point in doing Promise.resolve().then(function(){ return x; });? I found a snipped doing something similar (it called a function inside the then block). I thought it was more or less like doing a timeout, but it's a bit faster. jsben.ch/HIfDo

@Benjamin Gruenbaum 2020-02-13 20:49:56

There is no point it's the same as Promise.resolve(x) in 99.99% of cases. (the 0.001% is that we are in a with block over an object or proxy with an x property accessor that throws an exception. In that case Promise.resolve(x) would cause a thrown error but Promise.resolve().then(function(){ return x; }); would be a rejected promise since the error is thrown in a then).

@Sampgun 2020-02-14 08:01:21

you linked an empty blitz, or you didn't save. Anyway I wasn't talking about the differences among statements. I was talking precisely about what I wrote. Just to be more clear, this is the snippet I was talking about: if (validator) { Promise.resolve().then(() => { this._cdRef.markForCheck(); }); }. Here the promise isn't assigned, so what's the point? A timeout would have (more or less) the same effect, or not?

@Benjamin Gruenbaum 2020-02-14 17:12:42

It performs the call asynchronously after all synchronous code has happened but before any I/O happens. That's called "microtick semantics".

Related Questions

Sponsored Content

24 Answered Questions

[SOLVED] What is the difference between call and apply?

39 Answered Questions

[SOLVED] How do I return the response from an asynchronous call?

29 Answered Questions

35 Answered Questions

[SOLVED] What's the difference between using "let" and "var"?

7 Answered Questions

15 Answered Questions

8 Answered Questions

[SOLVED] What is the difference between Bower and npm?

  • 2013-09-05 16:53:19
  • Games Brainiac
  • 315667 View
  • 1771 Score
  • 8 Answer
  • Tags:   javascript npm bower

10 Answered Questions

Sponsored Content