• Javascript:再论Javascript的单线程机制 之 DOM渲染时机


    Javascript:再论Javascript的单线程机制 之 DOM渲染时机

    背景

    Javascript是单线程事件驱动的,所有能看到的Javascript代码都是在一个线程执行,定时器回调和AJAX回调会在适当的时刻插入队列等待Javascript线程调度执行,今天想测试一下DOM渲染的线程与时机,具体的问题是:

    修改DOM会立即显示在UI中吗?

    一个小测试

    测试代码

    复制代码
     1 <!DOCTYPE html>
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <head>
     4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     5     <title></title>
     6     <script src="Scripts/jquery-2.0.3.js"></script>
     7 </head>
     8 <body>
     9     <p>DOM的修改不会立马导致渲染,而是会内部触发一个事件(可能叫paint),这个事件的处理程序会被插入到Javascript的调度队列中等待调度执行。</p>
    10     <div id="Test1" style="height: 100px; margin: 5px; background-color: yellow;"></div>
    11 </body>
    12 </html>
    13 <script type="text/javascript">
    14 
    15     function sleep(millisecond) {
    16         var start = new Date().getTime();
    17 
    18         do {
    19             var end = new Date().getTime();
    20         } while (end - start <= millisecond);
    21     }
    22 
    23     setTimeout(function () {
    24         console.log('start...');
    25 
    26         $("#Test1").css({
    27             backgroundColor: 'red'
    28         });
    29 
    30         sleep(3000);
    31 
    32         console.log('...end');
    33     }, 2000);
    34 
    35 </script>
    复制代码

    测试结果

    DOM的修改不会立马导致渲染,而是会内部触发一个事件(可能叫paint),这个事件的处理程序会被插入到Javascript的调度队列中等待调度执行。

    一个小例子

    需求

    在DOM中显示1至20的斐波那契数组。

    实现

    复制代码
     1 <!DOCTYPE html>
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <head>
     4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     5     <title></title>
     6     <script src="Scripts/jquery-2.0.3.js"></script>
     7 </head>
     8 <body>
     9 <div id="Test2" style="height: 100px; margin: 5px; background-color: blue;"></div>
    10 </body>
    11 </html>
    12 
    13 <script type="text/javascript">
    14     setTimeout(function () {
    15         var fibonacci = function (n, callback) {
    16             if (n == 1 | n == 0) {
    17                 callback(n);
    18             }
    19 
    20             setTimeout(function () {
    21                 fibonacci(n - 1, function (n_1) {
    22                     fibonacci(n - 2, function (n_2) {
    23                         callback(n_1 + n_2);
    24                     });
    25                 });
    26             }, 0);
    27         }
    28 
    29         for (var i = 1; i <= 20; i++) {
    30             fibonacci(i, function (result) {
    31                 $("#Test2").append(result + '<br/>');
    32             });
    33         }
    34     }, 4000);
    35 </script>
    复制代码

    分析

    如果采用传统的递归方式,界面至少卡死N分钟,以这种形式递归,保证界面不至于卡死。

    备注

    时刻铭记:单线程+事件驱动。

  • 相关阅读:
    原型与原型链
    数据类型与计算
    JavaScript实现版本号比较
    vue依赖
    vue
    面试经验
    第十一节课 课堂总结
    第十一次作业
    第十课课堂总结
    第十次作业
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3247532.html
Copyright © 2020-2023  润新知