Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/460.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript console.log()是异步还是同步?_Javascript_Asynchronous - Fatal编程技术网

Javascript console.log()是异步还是同步?

Javascript console.log()是异步还是同步?,javascript,asynchronous,Javascript,Asynchronous,我目前正在阅读特雷弗·伯纳姆的作品。到目前为止,这是一本很棒的书 他谈到这个代码段和console.log在Safari和Chrome控制台中是“异步”的。不幸的是,我不能复制这个。代码如下: var obj = {}; console.log(obj); obj.foo = 'bar'; // my outcome: Object{}; 'bar'; // The book outcome: {foo:bar}; 如果这是异步的,我会预期结果将是books的结果。将console.log

我目前正在阅读特雷弗·伯纳姆的作品。到目前为止,这是一本很棒的书

他谈到这个代码段和console.log在Safari和Chrome控制台中是“异步”的。不幸的是,我不能复制这个。代码如下:

var obj = {}; 
console.log(obj); 
obj.foo = 'bar';
// my outcome: Object{}; 'bar';
// The book outcome: {foo:bar};
如果这是异步的,我会预期结果将是books的结果。将console.log()放在事件队列中,直到执行所有代码,然后运行它,它将具有bar属性

它似乎是同步运行的


我运行的代码错了吗?console.log实际上是异步的吗?

console.log
不是标准化的,因此行为没有定义,并且可以很容易地在不同版本的开发人员工具之间进行更改。你的书可能已经过时了,我的答案也可能很快就过时了

对于我们的代码来说,
console.log
是否异步没有任何区别,它不提供任何类型的回调等等;并且您传递的值总是在调用函数时被引用和计算

我们真的不知道接下来会发生什么(好吧,我们可以,因为Firebug、Chrome开发工具和Opera Dragonfly都是开源的)。控制台需要将记录的值存储在某个地方,并在屏幕上显示它们。渲染肯定会异步进行(被限制为速率限制更新),将来与控制台中记录的对象的交互(如扩展对象属性)也是如此

因此,控制台可以克隆(序列化)您记录的可变对象,也可以存储对它们的引用。第一种方法不适用于深/大对象。此外,至少控制台中的初始呈现可能会显示对象的“当前”状态,即登录时的状态-在您的示例中,您可以看到
object{}

但是,当您展开对象以进一步检查其属性时,控制台很可能只存储了对您的对象及其属性的引用,现在显示它们将显示它们的当前(已变异)状态。如果单击
+
,您应该能够在示例中看到
属性

以下是发布在中的屏幕截图,用于解释他们的“修复”:

因此,某些值可能在记录很久之后才被引用,而对这些值的计算相当缓慢(“在需要时”)。这种差异最著名的例子是在问题中处理的

解决方法是确保始终记录对象的序列化快照,例如通过执行
console.log(JSON.stringify(obj))
。不过,这只适用于非圆形和相当小的对象。另见


更好的解决方案是使用断点进行调试,在这里执行完全停止,您可以在每个点检查当前值。仅对可序列化和不可变数据使用日志记录。

使用console.log时:

a = {}; a.a=1;console.log(a);a.b=function(){};
// without b
a = {}; a.a=1;a.a1=1;a.a2=1;a.a3=1;a.a4=1;a.a5=1;a.a6=1;a.a7=1;a.a8=1;console.log(a);a.b=function(){};
// with b, maybe
a = {}; a.a=function(){};console.log(a);a.b=function(){};
// with b

在第一种情况下,对象足够简单,因此console可以“字符串化”它,然后呈现给您;但在其他情况下,a太“复杂”而无法“字符串化”,因此console将向您显示内存中的对象,是的,当您看到它时,b已经附加到a上了。

这并不是问题的真正答案,但对于偶然发现这篇文章的人来说,它可能很方便,而且太长时间无法发表评论:

window.console.logSync=(…args)=>{
试一试{
args=args.map((arg)=>JSON.parse(JSON.stringify(arg));
console.log(…args);
}捕获(错误){
console.log('尝试console.logSync()时出错,…args);
}
};
这将创建一个伪同步版本的
console.log
,但其注意事项与公认答案中提到的相同


由于目前大多数浏览器的
控制台.log在某种程度上是异步的,所以在某些情况下您可能需要使用类似的函数。

@thefourtheye:不,所以我可能应该删除我的注释。我在Chrome中看到过这种情况。如果您将console.log记录为一个简单对象,然后立即更改该对象中的某些内容,
console.log()
并不总是显示前一个值。如果发生这种情况,解决方法是将您尝试的
console.log()
转换为不可变的字符串,因此不受此问题的影响。因此,根据经验
console.log()
存在一些异步问题,可能与跨进程边界封送数据有关。这不是预期的行为,而是对代码>控制台.Log[A](代码)>内部工作的一些副作用(我个人认为它是一个bug)。参见@ BrGi,它花了我10分钟来找到这个DUPE(虽然我知道确切的名称),可能是因为它是DopeCoupe。我们能不能换一个复制品,让另一个成为复制品@乔纳斯·威尔姆斯我现在重新开始这个问题(见)。我不认为它们是相互重复的,我使用它们作为涉及数组的问题的规范目标。我知道这个问题已经存在3年了,但现在我遇到了同样的问题-序列化对象对我来说不起作用,因为它太复杂了。我正在捕获一个试图访问其数据的事件,但不知何故,它在代码中没有数据,但在console.log中有数据。我在console.log不异步时遇到了同样的问题。使用JSON.stringify在2019年的meAs中修复了它,我们可以说
console.log
在Chrome中仍然是异步的,因为它已经8年了(请参阅),唯一的变化是现在Chrome在调用
console.log
(如果展开logged对象,您将在
console.log
之后执行变异操作后看到其最终属性和值),或者
console.log
确实是同步的吗?@tonix是的,由于我的回答中列出的原因,这种行为不太可能改变。