0

Given this code, inside a simple Angular controller:

var s = $timeout(function() {
    console.log(s);
}, 2000 );

console.log(s);

$timeout(function() {
    $timeout.cancel(s);
}, 1000);

So we're creating a timeout in the variable s that's supposed to occur in 2 seconds. Then, 1 second into this, we cancel the timeout, so it never occurs. Before we cancel, however, we log s to the console. We would expect to see its status code to be 1 and its value to be undefined. Instead we see its status to be 2 and its value to be "canceled." Somehow, the system "knows" ahead of time that we're going to be cancelling the timeout and it adjusts accordingly.

What on earth! How is this happening? I would expect the state of object s to be like this after our $timeout.cancel(s); call. I certainly do not expect it before. What's going on here?

Here's the console after this code runs

Martyn Chamberlin
  • 1,277
  • 14
  • 17
  • Wow @SunilD. you are right. `console.log(s.$$state.status);` shows 0, while logging the entire object shows its status to be 2. – Martyn Chamberlin Mar 25 '16 at 18:59
  • 1
    Possible duplicates: http://stackoverflow.com/q/11214430/398606, http://stackoverflow.com/q/4057440/398606 ... I deleted my comment as it wasn't a good explanation. But hopefully these questions will help :) – Sunil D. Mar 25 '16 at 19:00
  • Yes, certainly related to that question, although (1) that person's problem no longer exists in modern browsers and I ascribe it as a technology limitation in terms of speed / performance (2) this question I've asked is more of a feature, not a limitation (Chrome's dev team could disable continued binding if they wished). But thanks! – Martyn Chamberlin Mar 25 '16 at 19:16

2 Answers2

2

Always serialize an object with

console.log(JSON.stringify(obj));

or by other means to output objects's snapshot and not its reference.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
0

So, it has nothing to do with the fact that the system "knows" ahead of time what's going to happen.

Instead, until you expand open an object that's been logged to a Chrome console, Chrome will continue to update all properties on that object as they get updated. Once you toggle open the object, however, you've frozen the values of its immediate properties. You have NOT, however, frozen the properties of any grandchildren.

I updated my code above to have a higher timeout.

var s = $timeout(function() {
    console.log(s);
}, 20000 );

console.log(s);

$timeout(function() {
    $timeout.cancel(s);
}, 10000);

If I toggle open both the Promise and the $$state in less than 10 seconds then I see the screenshot below. If I open Promise but not $$state in less than 10 seconds, I instead see its status set to 2.

enter image description here

Martyn Chamberlin
  • 1,277
  • 14
  • 17