Home  >  Q&A  >  body text

Is console.log() asynchronous or synchronous?

<p>I'm currently reading "Async Javascript" by Trevor Burnham. This is a great book so far. </p> <p>He talks about this snippet and console.log being "asynchronous" in the Safari and Chrome consoles. Unfortunately I can't replicate this. This is the code: </p> <pre class="brush:php;toolbar:false;">var obj = {}; console.log(obj); obj.foo = 'bar'; // my outcome: Object{}; 'bar'; // The book outcome: {foo:bar};</pre> <p>If this were asynchronous, I would expect the results to be what they are in the book. console.log() is put into the event queue until all code is executed, then it is run and has the bar attribute. </p> <p>Looks like it's running synchronously though. </p> <p>Am I wrong to run this code? Is console.log actually asynchronous? </p>
P粉248602298P粉248602298420 days ago491

reply all(2)I'll reply

  • P粉930534280

    P粉9305342802023-08-28 22:01:29

    This isn't really the answer to the question, but it might be handy for anyone who stumbles across this post and it's too long a comment:

    window.console.logSync = (...args) => {
      try {
        args = args.map((arg) => JSON.parse(JSON.stringify(arg)));
        console.log(...args);
      } catch (error) {
        console.log('Error trying to console.logSync()', ...args);
      }
    };
    

    This will create a pseudo-synchronous version of console.log but with the same warnings mentioned in the accepted answer.

    Since it appears that most browsers' console.log these days are asynchronous in some way, you may want to use a function like this in some cases.

    reply
    0
  • P粉141925181

    P粉1419251812023-08-28 15:47:19

    console.log is not standardized, so the behavior is rather undefined and can change easily between different versions of developer tools. Your book may be out of date, and my answers may soon be out of date.

    For our code, it makes no difference whether console.log is asynchronous or not, it doesn't provide any kind of callbacks, etc.; and the value you pass is always referenced and evaluated when you call the function.

    We don't really know what's going to happen next (well, we can, since Firebug, Chrome Devtools, and Opera Dragonfly are all open source). The console needs to store the logged values ​​somewhere and display them on the screen. Rendering will definitely happen asynchronously (subject to rate-limited updates), as will future interactions with objects logged in the console (such as extending object properties).

    So the console may clone (serialize) your logged mutable objects, or it may store references to them. The first one doesn't work with deep/large objects. Also, at least the initial render in the console might show the "current" state of the object, which is the state at the time of recording - in your example you'd see Object {}.

    However, when you expand the object to further examine its properties, the console may only store references to the object and its properties, showing them now will show its current (mutated) state. If you click on , you should be able to see the bar property in the example.

    Here is the screenshot posted in the bug report explaining their "fix":

    Therefore, some values ​​may not be referenced until long after they are recorded, and the evaluation of these values ​​is rather lazy ("when needed"). The most famous example of this difference is in the question Is Chrome's JavaScript console handling lazy evaluation of arrays?

    The workaround is to ensure that a serialized snapshot of the object is always logged, for example by doing console.log(JSON.stringify(obj)). However, this only works for non-circular and fairly small objects. See alsoHow to change the default behavior of console.log in Safari? .

    A better solution is to use breakpoints for debugging, where execution stops completely and you can inspect the current value at each point. Use logging only for serializable and immutable data.

    reply
    0
  • Cancelreply