事件循环是如何影响页面渲染的?

JavaScript Microtask setTimeout requestAnimationFrame Promise

JavaScript 是单线程的,但提供了很多异步调用方式比如 setTimeoutsetIntervalsetImmediatePromise.prototype.thenpostMessagerequestAnimationFrame, I/O,DOM 事件等。 这些异步调用的实现都是事件循环,但根据插入的队列不同和取任务的时机不同他们的表现也不同。 尤其在涉及与页面渲染的关系时。

TL;DR

  • 页面渲染/交互任务也会插入在 Task Queue 中,会与各种异步机制插入的任务交错执行。
  • Microtask Queue 会在下一个任务开始之前清空。
  • 单个耗时任务和 Microtask Queue 都会阻塞页面交互,Task Queue 则不影响。
  • 渲染时机可以通过 requestAnimationFrame 精确控制。
  • setImmediate 与 setTimeout 一样使用 Task Queue,但克服了 4ms 限制。

如何调试 Vim 脚本

Vim-Practice Vim 调试 日志

使用 -D 参数可以开启 Debug 模式, 在 Debug 模式中可以使用 cont, next, interrupt, step, quit 等调试命令, 以及 breakadd, breakdel 来添加和移除断点。 使用 -u 来禁止加载任何配置文件,使用 :source 命令逐个加载。 使用 :set verbose:set verbosefile配置变量 可以设置日志级别和输出文件, -V 启动参数也可以起到同样的作用。

Bash 条件判断

Bash Shell 变量 运算符

其实本文不是介绍 条件分支语法 的, 只介绍测试(test)语法,也就是说:本文只介绍如何写条件语法中的表达式。 其实本文介绍的内容也并未针对 Bash,多数 Shell 都是适用的。

与其他编程语言类似,if 的条件可以接受任何 表达式,计算为真就进入分支。 只是在 Bash 中表达式是一个命令调用

ES6 Symbol 的用途

ES6 Symbol 迭代器

Symbol 唯一的用途就是标识对象属性,表明对象支持的功能。 相比于字符属性名,Symbol 的区别在于唯一,可避免名字冲突。 这样 Symbol 就给出了唯一标识类型信息的一种方式,从这个角度看有点类似 C++ 的 Traits

ES6 迭代器:Iterator, Iterable 和 Generator

ES6 JavaScript 生成器 迭代器

对集合中每个元素进行处理是很常见的操作,比如数组遍历、对象的属性遍历。 以往这些操作是通过 for 循环、.forEach.map 等方式进行, 在 ES6 中直接把迭代放在语言层面进行支持,同时提供定制 for...of 的机制。 借由迭代器机制为 Map、Array、String 等对象提供了统一的遍历语法,以及更方便的相互转换。 为方便编写迭代器还提供了生成器(Generator)语法。

本文展开介绍了这些相关概念:Iterables(可迭代对象)、Iterator(迭代器)、 Generator(生成器)和 Generator Function(生成器函数), 以及相关机制:Iterable Protocol、Iterator Protocol、Symbol.iterator。

JavaScript 中数字的底层表示

JavaScript Number 浮点数 二进制 运算符

至今 JavaScript 已经有 6 种基本类型 了,其中数字类型(Number)是表示数字的唯一方法。 目前其标准维护在 ECMA262,在 JavaScript 语言层面不区分整数与浮点、符号与无符号。 所有数字都是 Number 类型,统一应用浮点数算术。 由于 JavaScript 中无法访问低层的二进制表示,而且 64 位可表示范围非常大,不容易遇到和了解到边界情况。 这篇文章对 JavaScript Number 的二进制表示进行简要的介绍,主要明确使用者观察到的边界, 解释 MAX_VALUE, MIN_VALUE, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER, EPSILON 这些常量取值的原因;回答 POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN 这些常量的表示方法。

下一页