当前位置:网站首页>关于JS console.log() 是同步 or 异步引发的问题
关于JS console.log() 是同步 or 异步引发的问题
2022-06-09 02:51:00 【知白守黑_】
发现问题
在学习《Vue.js设计与实现》渲染器部分的时候,发现在调用渲染函数之后修改虚拟DOM的值,渲染函数中拿到的是新的虚拟DOM。
const vnode = {
type: "div",
children: [
{
type: "p",
children: "text",
},
],
};
const app = document.querySelector("#app");
renderer.render(vnode, app);
vnode.children = [
{
type: "input",
props: {
value: "请输入关键字",
},
},
];
- 在渲染函数中打印虚拟DOM的值,发现结果为

把修改虚拟 DOM 的代码放入 setTimeout 函数中
setTimeout(() => {
vnode.children = [
{
type: "input",
props: {
value: "请输入关键字",
},
},
];
});
发现打印结果没有改变仍然是修改后的虚拟 DOM。
再将 setTimeout 的回调时间修改为 2000 ms,才得到了我想要的结果。
由此推测,渲染函数中存在有导致异步操作的代码。
定位问题
根据渲染流程,在代码中找到了可能导致异步的代码:
- document.createElement(localName, options);
- insertBefore(node, child)
接着去 Dom Standard 中查找这两个方法的具体定义:
在createElement的第六步中返回了 creating an element 的结果
于是去查看 creating an element的定义:
但是在定义中并没有找到和异步操作有关的信息。
接着去查看 insertBefore 的详细定义,结果也是一样,没有证据说明 insertBefore 涉及到了异步操作。
那么同步的操作却导致了异步的结果,那么问题很可能不是出在渲染函数中,于是我直接使用 console.log() 打印虚拟 DOM,果然,得到的是最新的虚拟 DOM:
console.log(vnode);
setTimeout(() => {
vnode.children = [
{
type: "input",
props: {
value: "请输入关键字",
},
},
];
});
查阅了一些帖子后发现有人提到在《你不知道的JavaScript中卷》中有问题的答案:
异步控制台
并没有什么规范或一组需求指定 console.* 方法族如何工作——它们并不是 JavaScript 正式的一部分,而是由宿主环境(请参考本书的“类型和语法”部分)添加到 JavaScript 中的。因此,不同的浏览器和 JavaScript 环境可以按照自己的意愿来实现,有时候这会引起混淆。
尤其要提出的是,在某些条件下,某些浏览器的 console.log(…) 并不会把传入的内容立即输出。出现这种情况的主要原因是,在许多程序(不只是 JavaScript)中,I/O 是非常低速的阻塞部分。所以,(从页面 /UI 的角度来说)浏览器在后台异步处理控制台 I/O 能够提高性能,这时用户甚至可能根本意识不到其发生。
举例
同时书中给出了解决方案:
如果遇到这种少见的情况,最好的选择是在 JavaScript 调试器中使用断点,而不要依赖控制台输出。次优的方案是把对象序列化到一个字符串中,以强制执行一次“快照”,比如通过 JSON.stringify(…)。
问题解决:
let vnodeStr = JSON.parse(JSON.stringify(vnode));
console.log(vnodeStr);

参考资料
- Dom Standard
- console.log是异步流?感觉自己貌似踩了个坑
- 《你不知道的JavaScript中卷》
边栏推荐
- What does the seven layer network structure do?
- Formatting and parsing of simpledateformat time
- Reflection principle and application in C #
- The difference between new and newinstance() for creating objects
- Two important influencing factors of togglerowselection() failure
- [untitled]
- Jerry last IO_ Key how to use double keys? [chapter]
- Container internal mysql5.7 configuration mode sqlmode + timeout wait_ timeout
- Leetcode 1352. Product of the last K numbers
- Ccf-csp 202104-1 gray histogram 100 points
猜你喜欢

LocalTime 、LocalDate 、LocalDateTime

视频边缘计算网关EasyNVR硬件以服务方式启动一直报错,如何排查及解决?

toggleRowSelection()失效的2個重要影響因素

Leetcode 871. Minimum refuelling times priority queue

C# 基础篇

现在VB6.0已经和SQL连接了,但是使用查询功能时无法做到任意条件查询,网上的情况和我的也不太相符,请问该如何实现呢?

Ccf-csp 201803-4 chess game evaluation +dfs

Go Technology Daily (2022 - 06 - 07) - go programer Development Efficiency God Summary

Go技术日报(2022-06-07)——go程序员开发效率神器汇总

Processes and threads
随机推荐
Leetcode 1185. Day of the week
[untitled]
qt项目添加编译报错选项
fatal error: juce_ core. h: No such file or directory
Formatting and parsing of simpledateformat time
Jerry last IO_ Key how to use double keys? [chapter]
Go Technology Daily (June 7, 2022) - go programmer development efficiency artifact summary
Greedy method / non 01 knapsack problem
vins estimator ProcessImage
TypeScript 基础类型 —— 类型断言
Leetcode 1155. N façons de rouler les dés
Ccf-csp 201903-3 damaged RAID5 70 points to be optimized
Ccf-csp 201403-3 command line options
Blue Bridge Cup_ Frog date_ Extended Euclid
Interface test series - interface test practice of transfer transaction business scenarios
Rcgi column - region of Overseas Social Market Research (including lottery)
New textbook for self taught examination-p292
How does JVM handle exceptions? The principle that finally blocks must execute?
toggleRowSelection()失效的2個重要影響因素
Modbus RTU communication routine between Delta Eh3 series PLC and thermostat