Is console.log() asynchronous or synchronous?
P粉248602298
2023-08-27 22:31:53
<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>
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:
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.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.