1

I've got this code:

let p1 = new Promise(function (resolve, reject) {
    setTimeout(function () {
        resolve({dogs: ['Fido', 'Spot']});
    }, 2000);
});

p1.then(function (val) {
    console.log('first then');
    console.dir(val);
    return _.extend(val, {cats: ['Fluffy', 'Whiskers']});
}).then(function (val) {
    console.log('second then');
    console.dir(val);
});

The unexpected console output shows:

enter image description here

I don't understand how cats could possibly be part of the value before it's actually appended into the object. The results printed in the second then make sense to me though. Am I missing something?

ffxsam
  • 26,428
  • 32
  • 94
  • 144
  • See the `i` popup in the console. You're seeing the later-mutated object. – SLaks Sep 17 '15 at 21:35
  • It says "Object state below is captured upon first expansion." I don't even know what that means... – ffxsam Sep 17 '15 at 21:36
  • is _.extend() from underscore.js? – keheliya Sep 17 '15 at 21:45
  • @keheliya I rejected your tag edit, as the question is not really about Underscore and Underscore's usage here is irrelevant. – ffxsam Sep 17 '15 at 21:48
  • 2
    possible duplicate of [Is Chrome's JavaScript console lazy about evaluating arrays?](http://stackoverflow.com/questions/4057440/is-chromes-javascript-console-lazy-about-evaluating-arrays) – Felix Kling Sep 18 '15 at 00:26
  • This has nothing to do with promises and everything to do with how the console works. – Felix Kling Sep 18 '15 at 00:26
  • possible duplicate of [console.log() async or sync?](http://stackoverflow.com/questions/23392111/console-log-async-or-sync) – Bergi Sep 18 '15 at 16:10

2 Answers2

1

You're adding the cats property to the same object you already logged.

As the i icon tells you, the console only reads the properties of the object when you actually expand it.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 2
    Because serializing stuff is slow. If you logged a really large object often, it would bring your tab to a grinding halt. Plus not all objects are trivially copyable, so even just making a copy isn't well defined. If you want it at the time, just do `console.log(JSON.stringify(obj, null, 2));` instead, or do `_.extend({}, val, {cats: ['Fluffy', 'Whiskers']});` so you don't mutate the original value. – loganfsmyth Sep 17 '15 at 23:50
  • @loganfsmyth I agree JSON.stringify is a possible workaround. – inf3rno Sep 18 '15 at 03:58
  • @loganfsmyth: Please don't forget to vote to close as duplicate :-) – Bergi Sep 18 '15 at 16:11
0

As far as I know there is a bug in console.log by ES6 Promises. It waits for a few seconds before it logs the value of your object, that's why it contains the cats. If I remember well, this bug happens in firefox. I don't know how it behaves by the other browsers.

inf3rno
  • 24,976
  • 11
  • 115
  • 197
  • 1
    It's just with `console.log` though. If I do an `alert`, it works as expected. And this console issue appears in both FF and Chrome. – ffxsam Sep 17 '15 at 21:49
  • 1
    @ffxsam Yepp. This is a known bug. I don't think you need to report it, maybe add a +1 somewhere, if you find the existing reports. – inf3rno Sep 17 '15 at 21:50
  • It's not a bug, it's a feature. – loganfsmyth Sep 17 '15 at 23:55
  • @loganfsmyth Ye we all know that: `bug + won'tfix = feature`. – inf3rno Sep 18 '15 at 02:54
  • I kind of meant it honestly really. See my other comment. It might be a little surprising at times, but there isn't really any way you could do deep introspection of an object and NOT do it like it is. – loganfsmyth Sep 18 '15 at 03:51