博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
我不该动你的,Event Loops(深坑)
阅读量:6222 次
发布时间:2019-06-21

本文共 2108 字,大约阅读时间需要 7 分钟。

我不该动你的,Event Loops

写在前面的话

本意是想好好研究下 Event Loops, 看了几篇博客后,才意识到作为前端打字员的我有多无知,这坑忒深了。

macrotask?,microtask?,MutationObserver? 这些都是啥?规范还没写清楚?不同浏览器运行的还未必一样?

但为了使自己养成经常总结的习惯,还是写点什么吧。

故事的开始

  

计算 fib(45) 是一个相当耗时的工作,在我的chrome里约需要15s左右。

问,页面什么时候会变成红色?在执行 console.now(1) 之前就变成红色了吗?

e01

可以看到即使在 console.now(1) 执行之后,页面仍旧没有变红。

关于这个现象,可以有两种解释:

  1. document.getElementsByTagName('body')[0].style.backgroundColor = 'red' 被当作一个异步事件,作为一个 task,被添加到 event loops
  2. 渲染引擎要等到 JS 引擎空闲时才开始工作

到底是哪一种?所以将上述代码修改下

又增加了一个 setTimeout。这样的话,如果是第一种解释,应该在 console.now(3) 运行之前,页面就变成了红色;否则就应该采取第二种解释。

运行结果如下,

e02

可以看到在 console.now(3) 之后,页面依旧没有变色,看来就是渲染引擎要等到JS引擎完全空闲时才工作。

事情就这样结束了吗

没有,直到我看到

An must continually run through the following steps for as long as it exists:

  1. Let oldestTask be the oldest on one of the 's , if any, ignoring, in the case of a , tasks whose associated Documents are not . The user agent may pick any . If there is no task to select, then jump to the microtasks step below.
  2. Set the 's to oldestTask.
  3. Run oldestTask.
  4. Set the 's back to null.
  5. Remove oldestTask from its .
  6. Microtasks: .
  7. Update the rendering: If this is a (as opposed to a ), then run the following substeps.

    …...

这段话第7点的意思,怎么理解起来像是每执行一次 Event Loops 的 task,最后都会更新视图。

后来看到中

渲染更新(Update the rendering)会在event loop中的tasks和microtasks完成后进行,但并不是每轮event loop都会更新渲染,这取决于是否修改了dom和浏览器觉得是否有必要在此时立即将新状态呈现给用户。

会不会两次 setTimeout 被合并了?

e04

这样调整之后,在运行 console.now(3) 之前,页面的颜色就变了

这样看来,就是在每一次task之后就可能会更新视图,而不是等到JS引擎空闲

在执行完setTimeout0后,Event Loops 中实际上仍有 setTimeout1 待执行,但是浏览器先渲染了视图,再执行了setTimeout ,这就推翻了之前渲染引擎要等到 JS 引擎空闲(Event Loops为空)时才开始工作。

同时我怀疑,之前代码

setTimeout(function () {      console.now(0)      document.getElementsByTagName('body')[0].style.backgroundColor = 'red'      console.now(1)      fib(45)      console.now(2)    }, 1000)    setTimeout(function () {      console.now(3)      fib(45)      console.now(4)    }, 1000)

会不会被优化成

setTimeout(function () {      console.now(0)      document.getElementsByTagName('body')[0].style.backgroundColor = 'red'      console.now(1)      fib(45)      console.now(2)      console.now(3)      fib(45)      console.now(4)    }, 1000)

坑深,今天先到这,休息下了

参考资料

转载地址:http://nzgja.baihongyu.com/

你可能感兴趣的文章
jquery div弹出层方式,显示页面内容
查看>>
函数式编程学习之路(10)
查看>>
TextView --- 内容设置成上下滑动 和 代码设置字体颜色
查看>>
数组距离MST_prim
查看>>
客户传真第四部分 个人理财风险防范8.当心银行汇款引发的诈骗
查看>>
php 事件驱动 消息机制 共享内存
查看>>
分享一个IIS日志分析工具-LogParse
查看>>
Silverlight中使用Grid创建自定义的Table表格
查看>>
Console-算法[for,if]-不用第三个变量,交换两字符串的值
查看>>
Hadoop入门(一):Hadoop伪分布安装
查看>>
Tomcat环境配置
查看>>
屌丝程序员的那些事(一)-毕业那年
查看>>
CWidgetMgr---H
查看>>
spring测试实例
查看>>
创建Sdcard
查看>>
两个数组a[N],b[N],其中A[N]的各个元素值已知,现给b[i]赋值,b[i] = a[0]*a[1]*a[2]…*a[N-1]/a[i];...
查看>>
cocos2d-x与ISO内存管理(转)
查看>>
磁盘I/O的性能评估方法
查看>>
计算机排序算法
查看>>
普通IT和文艺IT工程师的区别
查看>>