了解JavaScript中的异步处理(1)执行模型和任务队列(1)

然而,规定与 "承诺 "有关的工作必须在同一个队列中。

工作 必须按照安排它们的HostEnqueuePromiseJob调用的相同顺序运行。

这确保了以下程序将依次输出0-9。

(async () => { for(let i = 0; i < 10; i += 2) console.log(await i); })()。

(async () => { for(let i = 1; i < 10; i += 2) console.log(await i); })()。

截至2021年,ECMAScript标准中没有定义与Promise无关的工作。这些将在其他规范中被额外定义,如HTML。

从今以后,我们将使用自己的术语,把一个microtick定义为Promise作业队列的一个周期。

web浏览器任务队列

=============================================================================

ECMAScript作业在HTML规范中被称为任务。队列中还加载了ECMAScript作业以外的任务。该队列分为两种类型

  • 正常)任务队列

  • 可以有多个(正常)任务队列,用于不同类型的任务(取决于实施)。

  • 微任务队列

  • 排在微任务队列中的任务被称为微任务

在ECMAScript规范中,所有的任务队列和微任务队列一起被认为是一个作业队列

requestIdleCallback中定义的空闲回调列表/可运行回调列表也可以被视为任务队列的一个变体

事件循环的处理在§8.1.6.3中规定,与本文相关的内容可归纳为以下几点

  • 如果在任务队列中有一个任务,它将被检索和执行。

  • 微任务队列中的任务被获取并逐一执行,直到没有更多的任务。

  • 更新图纸。

  • 如果任务队列中有空间,背景任务将根据 RequestIdleCallback 规范进行排队。

  • 从头开始

这意味着

  • 微型任务比普通任务有优先权。

  • 微型任务的优先级高于绘图。

微任务比普通任务有优先权,这意味着它们会饿死。下面的等待忙碌循环对浏览器的负面影响几乎和无限循环一样,因为它阻断了绘图。

(async () => {

while(true) {

await null;

}

})();

有两种典型的方法来排队等候微任务

  • 功能排队微任务

  • Promise.prototype.then函数。这个实体的HTML规范实现, HostEnqueuePromiseJob,要被加载到一个微任务队列中。

  • 这也是async/await中的await的情况。

另一方面,要显式地排队等候一个正常的任务并不容易。另一方面,要显式地对一个普通的任务进行排队并不容易,因为任务通常是由一些事件来排队的。 在 用于网络浏览器环境的setImmediate的polyfill中,使用了以下实现。

  • 在窗口代理下,你可以通过向自己发送 window.postMessage 来启动一个事件

  • 在Worker代理下,使用 MessageChannel postMessage

  • 使用 setTimeout 作为退路

我们使用自己的术语,将一个microtick定义为网络浏览器环境中微任务队列的一个周期。这与上一节中的定义是一致的。我们还将 任务队列周期定义 为一个tick,这是我们自己的术语。

Node.js任务队列

==============================================================================

Node.js是基于Chrome的JavaScript引擎V8,任务的概念与网络浏览器相似。(queueMicrotask 和 Promise.prototype.then 是可用的)

除了微任务队列之外 process.nextTick 队列是Node.js的一个特性。一般来说, process.nextTick 优先于微任务,但如果它在一个微任务中被排队,它的处理优先级将低于其他微任务。这是因为任务队列是按以下顺序处理的

while(true) {

waitForAnyTask();

if (taskQueue.length > 0) taskQueue.pop().run();

do {

while (nextTickQueue.length > 0) nextTickQueue.pop().run();

while (microtaskQueue.length > 0) microtaskQueue.pop().run();

} while (nextTickQueue.length > 0);

}

process.nextTick 的存在是为了Node.js内置的I/O处理和历史原因。对于Node.js中内置的I/O处理,由于历史原因,现在推荐使用 queueMicrotask 。

与浏览器中的JavaScript不同,Node.js还提供了一个函数 setImmediate ,可用于将任务排入常规任务队列 。它的使用方式与 setTimeout 基本相同。

// 在执行之前处理当前的I/O任务等。

setImmediate(() => console.log(“Hello!”))

在Node.js环境中,微任务队列的一个周期在我们自己的术语中被定义为一个Microtick。这与上一节中的定义是一致的。我们也把我们自己的术语定义 为一个任务队列周期,即一个tick

setTimeout

=============================================================================

一个旧的API用于在一定时间后排队任务,而不是直接排队,这就是 setTimeout ,它在网络浏览器和Node.js中都有实现。

setTimeout(() => console.log(“1 second has passed”), 1000);

网络浏览器和Node.js之间有许多不同之处

  • 最小秒数的行为差异(见下文)。

  • 在Node.js中,处理程序不能作为字符串传递。

  • 在Node.js中,返回的是一个定时器对象(Timeout),而不是一个定时器ID(数字)。

  • Node.js允许对定时器事件进行ref/unref操作。

浏览器

  • 时间的下限最初是0ms,但如果 setTimeout / setInterval 嵌套了5层以上,则为4ms。

  • 允许你等待的时间超过规定的时间

这里的嵌套指的是在 setTimeout 回调任务中调用 setTimeout 而增加的值。

// ← nesting level = 0

setTimeout(() => {

// ← nesting level = 1

setTimeout(() => {

// ← nesting level = 2

setTimeout(() => {

// ← nesting level = 3

setTimeout(() => {

// ← nesting level = 4

setTimeout(() => {

// ← nesting level = 5

setTimeout(() => {

// ← nesting level = 6

// nesting level > 5

setTimeout(() => {

// ← nesting level = 7

}, 0);

}, 0);

}, 0);

}, 0);

}, 0);

}, 0);

}, 0);

从历史上看,似乎类似的规则在实施时,每个浏览器的规则都略有不同

Node.js

==========================================================================

  • 时间的下限是1ms,四舍五入为毫秒的整数值(截断)。

  • 不能保证你会准确地等待你所指定的时间,你有可能被向前或向后推迟。

// 在1毫秒后运行

setTimeout(() => console.log(“foo”), 0.5);

// 5毫秒后运行

setTimeout(() => console.log(“foo”), 5.1);

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档,需要的读者可以戳这里免费领取!

是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档,需要的读者可以戳这里免费领取!

[外链图片转存中…(img-Ujp4TaFm-1712273871825)]

[外链图片转存中…(img-rThClGZe-1712273871825)]

  • 25
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值