- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
从我对 javascript 虚拟机如何工作的整体理解来看,我可以清楚地看到微任务/宏任务的概念发挥着重要作用。
<小时/>这是我对此的理解:
这是我的问题的要点:
为什么没有明确的 API 来操作这两个队列。
类似于
pushToMacroTask( 函数 )
pushToMicroTask( 函数 )
实际上,操作这些队列的唯一方法似乎是使用 setTimeout()
将任务添加到宏任务队列,使用 Promises
将任务添加到微任务队列任务队列...
我对此表示同意,但这并没有给我们一个有意义的 API,你不觉得吗?
这个概念是否应该对 JS 开发人员保持“隐藏”并且仅在某些 hacky 情况下使用?
您知道是否有关于该主题的任何 W3C 规范吗?
所有 VM 引擎都以相同的方式实现这个概念吗?
我很高兴听到有关这方面的故事和意见。
谢谢!
最佳答案
W3C 谈到 task queues :
When a user agent is to queue a task, it must add the given task to one of the task queues of the relevant event loop. All the tasks from one particular task source (e.g. the callbacks generated by timers, the events dispatched for mouse movements, the tasks queued for the parser) must always be added to the same task queue, but tasks from different task sources may be placed in different task queues.
EcmaScript2015 谈到 Job Queues ,并要求至少支持两个:
- ScriptJobs: Jobs that validate and evaluate ECMAScript Script and Module source text.
- PromiseJobs: Jobs that are responses to the settlement of a Promise.
此语言定义不知道可能的事件循环,但可以想象保留一个或多个作业队列以与 W3C 规范中提到的任务队列一起使用。浏览器将根据链接到作业队列的 W3C 任务队列规范触发 setTimeout
回调,而 Promise必须直接使用作业队列规范(不是任务队列)。还提到了代理可以将任务注入(inject)作业队列:
Alternatively, [an implementation] might choose to wait for a some implementation specific agent or mechanism to enqueue new PendingJob requests.
EcmaScript 规范不强制规定服务不同作业队列的优先级:
This specification does not define the order in which multiple Job Queues are serviced. An ECMAScript implementation may interweave the FIFO evaluation of the PendingJob records of a Job Queue with the evaluation of the PendingJob records of one or more other Job Queues.
因此,这里似乎没有严格要求 promise 履行应在 setTimeout
任务之前提供服务。但网络超文本应用技术工作组 [WHATWG] 在涵盖 event loops 时更加具体。 :
Each event loop has a microtask queue. A microtask is a task that is originally to be queued on the microtask queue rather than a task queue.
[2019年新增]:同时Living HTML Standard [WHATWG] 现在包括以下内容:
8.6 Microtask queuing
self.queueMicrotask(callback)
Queues a microtask to run the given callback.
The
queueMicrotask(callback)
method must queue a microtask to invokecallback
, and ifcallback
throws an exception, report the exception.The
queueMicrotask()
method allows authors to schedule a callback on the microtask queue. This allows their code to run after the currently-executing task has run to completion and the JavaScript execution context stack is empty, but without yielding control back to the event loop, as would be the case when using, for example,setTimeout(f, 0)
.
从历史上看,不同的浏览器实现会导致不同的执行顺序。这个article从 2015 年开始,读起来可能会很有趣,看看它们有多么不同:
Some browsers [...] are running promise callbacks after
setTimeout
. It's likely that they're calling promise callbacks as part of a new task rather than as a microtask.Firefox and Safari are correctly exhausting the microtask queue between click listeners, as shown by the mutation callbacks, but promises appear to be queued differently. [...] With Edge we've already seen it queues promises incorrectly, but it also fails to exhaust the microtask queue between click listeners, instead it does so after calling all listeners.
从那时起,几个问题已经得到解决和协调。
但请注意,不必有一个个微任务队列,也不必有一个个宏任务队列。可以有多个队列,每个队列都有自己的优先级。
实现你建议的两个功能当然不是那么困难:
let pushToMicroTask = f => Promise.resolve().then(f);
let pushToMacroTask = f => setTimeout(f);
pushToMacroTask(() => console.log('Macro task runs last'));
pushToMicroTask(() => console.log('Micro task runs first'));
[2019] 现在我们有了 queueMicrotask()
,有一个 native 实现。下面是一个演示,将该方法与上面基于 Promise 的实现进行比较:
let queuePromisetask = f => Promise.resolve().then(f);
let queueMacrotask= f => setTimeout(f);
queueMicrotask(() => console.log('Microtask 1'));
queueMacrotask(() => console.log('Macro task'));
queuePromisetask(() => console.log('Promise task'));
queueMicrotask(() => console.log('Microtask 2'));
关于用于显式添加微任务或宏任务的 Javascript API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41075724/
如何在 Excel 中编写可以在我将打开的任何 Excel 文档上工作(使用快捷方式运行)的宏? 这可能吗? 最佳答案 您需要将宏添加到 Personal.xlsb 以使它们可用于所有 excel 文
我正在研究 problem #74在4clojure.com,我的解决方案如下: (defn FPS [s] (->> (map read-string (re-seq #"[0-9]+"
我还没有完全理解Clojure 箭头宏thread-first -> 和thread-last 宏->> 之间的区别。在阅读 https://clojure.org/guides/threading_
我想将一些调试输出语句插入到大型 C 代码库中。这些调试输出语句将由编译器选项开关控制。 调试输出语句如下所示: #ifdef DEBUG_FLAG Print(someSymbol) #endif
我正在通过宏将代码注入(inject)到 C++ 类中。有没有办法根据访问修饰符的上下文来做到这一点?有点像 #if (we_are_in_public_context) INJECT_PUBLIC_
这应该与 memoize 类似,但有很大不同。虽然 memoize 应该与纯函数一起使用,但它通常对加速 IO 相关函数很有用。 我正在寻找的函数/宏应该表现得像高阶函数。它产生的功能应该: 第一次调
对于下面的代码: let services: [MyServices] = [ MyService(), #if DEBUG DebugService(), #endi
假设我有以下文本文件 name: John Doe description: My name is John Doe and I'm really good at vim! name: John Do
在创建 Excel 宏方面需要帮助。我有一个 Excel 工作表。Excel 工作表不一致。我打算使它统一和结构化。 例如。 A B C
我正在 excel 中设置一个宏,以便在更新单元格时自动发送电子邮件。是否可以在电子邮件正文中包含单元格的内容?例如,如果单元格 G7 已更新,请在电子邮件中包含单元格 B7 的内容?单元格行将是相同
我创建了一个简单的 Excel 工作表。 这是我的宏代码: Sub MyMacro() Sheets("Sheet1").Select A$ = Cells(1, 1) Msg
在 Excel 的 VB 宏中,如何删除所有出现的以某个字符串开头的单词? 例如: 字符串内容为:xxxx $AUD543.43 yyyy 我想搜索以 $AUD 开头的字符串中的任何内容并删除下一个空
我是 Excel 宏的新手.. 谁能告诉我这个宏是做什么的? Sub People_Add_Document() prow = ActiveCell.row num = Cells(p
我对 Excel 中的 VBA 和宏非常陌生。我有一个非常大的 Excel 电子表格,其中 A 列保存日期。我正在尝试删除值小于某个日期的行,这就是我到现在为止的想法。 Sub DELETEDATE(
我在 Excel 2003 中有一个 VBA 对象,当通过流数据获得某些值时,它会触发三个简单的宏。它运行良好。我想打开一个重复的工作表,但具有不同的流数据,并在各自的工作表上触发宏。它现在可以使用,
下面的宏有什么问题?我只想评估一个选项卡中的一个单元格是否大于另一个选项卡中的另一个单元格。然后消息框: Sub Comhouse() If Worksheets("(2.2) TRA works
需要一个简单的 excel 宏的帮助。我在第 1 列 X1 到 X20 中有数据。我想自动将此信息粘贴到 A 列,然后当我更新 X 列中的数字时,我想将此信息粘贴到 B 列,然后再粘贴到 C 列...
我找到了以下代码,效果很好;但是,我必须手动更改月份,以便它转到第二个工作簿的右侧工作表。由于工作表以月为单位,我怎样才能使其自动更改为当月? Sub AlarmSheet() Dim wkb As
很难说出这里问的是什么。这个问题是模棱两可的、模糊的、不完整的、过于宽泛的或修辞的,无法以目前的形式得到合理的回答。如需帮助澄清这个问题以便重新打开它,visit the help center .
我的公司只使用 MS Office 2003 产品,所以我必须坚持下去。由于我的工作性质,我需要使用很多“复制和粘贴”功能。源数据主要来自网站,我将数据粘贴到 Excel 中的单元格中。问题是剪贴板保
我是一名优秀的程序员,十分优秀!