我有一个非常大的对象,它变成了一个非常非常大的JSON字符串。
我有一个点击监听器
randomElement.addEventListener("click", function(){
console.log("should log immediately");
var content = encodeURIComponent(JSON.stringify(veryLargeJson));
});
在eventListener范围之外声明/更新了veryLargeJson。
无论出于什么原因,当我点击元素时,浏览器微调器会出现,因为它会尝试对veryLargeJson进行字符串化然后对其进行编码,但这会在登录控制台之前发生。
世界上到底发生了什么?为什么浏览器不按顺序执行JSON.stringify。
我的第一个想法是,一般工作中事件监听器闭包或闭包的方式可能是首先执行变量声明,或者在发生任何其他事件之前解析所有变量。例如,如果我的非常大的json在生成点击的范围之外的范围内声明,那么浏览器会立即尝试解析非常大的json是什么,并且这样做会因为json如此大而冻结,然后继续并打印出我的控制台日志,然后才将其分配给我在监听器中声明的局部变量。
这是发生了什么事吗?
UPDATE ---------------------------------------------- ---------------------
我已将上述问题留给了上下文。
当事件侦听器闭包中存在formData对象并且正在使用非常大的json字符串附加到formData对象时发出ajax请求时,会出现此问题。
所以现在我的问题是,为什么闭包会不按顺序评估xhttp.send参数?
randomElement.addEventListener("click", function(){
console.log("should log immediately");
var content = encodeURIComponent(JSON.stringify(veryLargeJson));
var formData = new FormData();
formData.append("whatever", content);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "https://randomEndpoint", true);
xhttp.setRequestHeader("cache-control", "no-cache");
xhttp.send(formData);
});
答案 0 :(得分:1)
浏览器无法处理"无序"。除非Web工作者在游戏中,否则所有处理都在事件处理程序和单线程中完成。
可能会发生的事情是观察 stringify
来电后出现的控制台日志,但仍然是之前完成的。
当它看起来可见时,取决于浏览器的GUI事件循环,通常GUI更新只是排队的事件,因此它们必须等待点击的事件才能完成处理(除非你启动一个嵌套的事件循环 - 在只有alert
和朋友才能使用Javascript。
如果您在console.log(+ new Date())
来电之前和之后添加stringify
,您会发现操作需要很长时间。