5

The relevant question told me that resolving to a new promise, which is scheduled for the next loop even though it's immediately resolved. However, the comment part seems to be counter examples.

var p1 = Promise.resolve("p1")

/* console order will be "p2" "p1" */ 
// pattern1
// var p2 = Promise.resolve(Promise.resolve("p2")); 
// pattern2
// var p2 = Promise.resolve(new Promise(function(resolve, reject){
//   resolve("p2")
// }))

/* console order will be "p1" "p2" */ 
// pattern3
var p2 = new Promise(function(resolve, reject){
    resolve(Promise.resolve("p2"));
}) 

p2.then(function(value){
  console.log(value);
})
p1.then(function(value){
  console.log(value);
})

weird in Chrome v61.0.3163.91, but normal in Node.js.

NOTE: the question is not the same with the popular one. Just focus on the order question: Why the different patterns produce different order? And explaination in terms of Event Loop would be preferred.

Ye Shiqing
  • 1,519
  • 2
  • 15
  • 24

2 Answers2

3

promise.then's callback won't be appended to the microtask queue until the promise is in the status of settled(fulfilled or rejected). Microtask will be executed sequentially from queue, i.e. "First In, First Out".

In the implementation of Chrome v61.0.3163.91, once p1 created, it is always in the status of resolved. p2 in pattern1 and pattern2 are in the status of resolved, while p2 in pattern3 are in the status of pending.

Therefore, in pattern1 and pattern2, p2.then's callback is appended to the microtask queue first and executed first. In pattern3, although p2.then is executed first, it appends the callback to the microtask queue in the future, since the promise is still in the status of pending. So p1.then's callback executed first.

Ye Shiqing
  • 1,519
  • 2
  • 15
  • 24
0

The commented .then() logs result in the order which the code is called.

// logs `"p1"`, `"p2"`
var p1 = Promise.resolve("p1")

var p2 = Promise.resolve(Promise.resolve("p2")); 

p1.then(function(value){
  console.log(value);
})

p2.then(function(value){
  console.log(value);
})

// logs `"p2"`, `"p1"`
var p1 = Promise.resolve("p1")

var p2 = Promise.resolve(Promise.resolve("p2")); 

p2.then(function(value){
  console.log(value);
})

p1.then(function(value){
  console.log(value);
})
guest271314
  • 1
  • 15
  • 104
  • 177
  • sure, but I guess the OP wants to know why? – Jaromanda X Sep 23 '17 at 08:40
  • @JaromandaX Why as to what specifically? Why the code is called in the order OP calls the code? – guest271314 Sep 23 '17 at 08:41
  • Why the different patterns produce different order – Jaromanda X Sep 23 '17 at 08:42
  • @JaromandaX Which code are you referencing now? The commented code or the uncommented code? – guest271314 Sep 23 '17 at 08:43
  • The difference between the 3 different patterns of p2. That's just my interpretation of the question and comments in the op code – Jaromanda X Sep 23 '17 at 08:45
  • @JaromandaX The extra call to `Promise.resolve()` within `Promise` constructor is the difference between the patterns. Remove the extra `Promise.resolve()` and the result should be `"p2"`, `"p1"` `var p1 = Promise.resolve("p1") var p2 = new Promise(function(resolve, reject){ resolve( "p2" ); }); p2.then(function(value){ console.log(value); }) p1.then(function(value){ console.log(value); })`. It would probably be helpful if the patterns were labeled so that we would be clear about which code we are referencing. – guest271314 Sep 23 '17 at 08:50
  • 2
    yeah ... but why is `var p2 = new Promise(function(resolve, reject){ resolve(Promise.resolve("p2")); })` different to `var p2 = Promise.resolve(new Promise(function(resolve, reject){ resolve("p2") }))` - I would've expected all 3 to output p2 then p1 (like it does in node) – Jaromanda X Sep 23 '17 at 08:54
  • @JaromandaX Not sure why. Am not inclined to speculate. Am on version 30 of a piece of code where could have concluded earlier in development were it not for different implementations at different browsers. Had to keep asking questions. And now there is discussion as to deprecating one of the properties of the object which finally culminated in code which returns same result at each browser, that is chromium and firefox. Would ask the relevant implementers (blink, gecko, etc.) using the same code - though clearly labeled for each version - and let the implementers explain their implementation. – guest271314 Sep 23 '17 at 08:59
  • @guest271314 I don't think the answer is relative to my question. I have read all the comments and reedit my question. Could you adjust your answer to focus on the order confusion in the scenerio of my question? I think it will be a good answer. – Ye Shiqing Sep 24 '17 at 01:50
  • @PageYe Given the code at Answer, the result depends on which `.then()` is placed before the adjacent `.then()` as demonstrated by code at stacksnippets. What additional description should be added to Answer? – guest271314 Sep 24 '17 at 01:55
  • @PageYe `Promise.race([Promise.resolve(1), new Promise(resolve => resolve(2))]) .then(res => console.log(res))`, `Promise.race([new Promise(resolve => resolve(2)), Promise.resolve(1)]) .then(res => console.log(res))` should further illustrate that the result of `Promise.resolve()` or `Promise` constructor reaching `.then()` first depends on which is called before the other. – guest271314 Sep 24 '17 at 02:06
  • @guest271314 How can u explain the different result between pattern2 and pattern3 in the codes of my quesition? It's not related to the `which .then() is placed before the adjacent .then()` – Ye Shiqing Sep 24 '17 at 02:53
  • 1
    @PageYe The difference is call to `Promise.resolve()` within `p2` `Promise` constructor. When code is `var p2 = new Promise(function(resolve, reject){ resolve("p2"); })` `"p2"` is logged first at `console`. Would suggest filing an issue at https://bugs.chromium.org/p/monorail/issues/list to ask implementers of `Promise` at Chromium browser for specific details and explanation of their implementation of `Promise` – guest271314 Sep 24 '17 at 04:57