gpt4 book ai didi

javascript - 引入一个单独的微任务队列的动机是什么,事件循环优先于任务队列?

转载 作者:行者123 更新时间:2023-12-03 16:31:46 25 4
gpt4 key购买 nike

我对JS中异步任务如何调度的理解
如果我有任何错误,请纠正我:
JS 运行时引擎代理由一个事件循环驱动,它收集任何用户和其他事件,将任务排入队列以处理每个回调。
事件循环持续运行,并具有以下思考过程:

  • execution context stack (通常称为调用栈)空?
  • 如果是,则将微任务队列(或作业队列)中的任何微任务插入调用堆栈。继续这样做,直到微任务队列为空。
  • 如果微任务队列为空,则将任务队列(或回调队列)中最早的任务插入调用栈

  • 因此,任务和微任务的处理方式有两个主要区别:
  • 微任务(例如 promises 使用微任务队列来运行它们的回调)优先于任务(例如来自其他 Web API 的回调,例如 setTimeout)
  • 此外,所有微任务都在任何其他事件处理或呈现或任何其他任务发生之前完成。因此,微任务之间的应用环境基本相同。

  • Promise 是在 ES6 2015 中引入的.我假设微任务队列也在 ES6 中引入。
    我的问题
    引入微任务队列的动机是什么?为什么不继续使用任务队列进行 Promise 呢?
    更新#1 - 我正在寻找对规范进行此更改的明确历史原因 - 即它旨在解决的问题是什么,而不是关于微任务队列好处的固执己见的答案。
    引用:
  • In depth: Microtasks and the JavaScript runtime environment
  • HTML spec event loop processing model
  • Javascript-hard-parts-v2
  • loupe - 可视化工具,了解 JavaScript 的调用栈/事件循环/回调队列交互
  • Using microtasks in JavaScript with queueMicrotask()
  • 最佳答案

    Promises were introduced in ES6 2015. I assume the microtask queue was also introduced in ES6.


    实际上,ECMAScript 标准根本没有引入微任务任务队列:ES6 标准指定将 promise 处理作业放置在一个名为“PromiseJobs”的队列中,位于 TriggerPromiseReactions 下。 ,使用抽象流程 EnqueueJob将作业输入到主机环境实现的作业队列中,而不规定主机队列应该如何处理。
    在 ECMAScript 采用之前
    Promise 库是在用户领域开发的。执行 promise 处理程序的代码位,监视它们是否抛出或返回值并有权访问 resolvereject promise 链中下一个 promise 的功能称为“蹦床”。虽然是 Promise 库的一部分,但 Trampoline 不被视为用户代码的一部分,并且声称使用干净的堆栈调用 Promise 处理程序排除了 Trampoline 占用的堆栈空间。
    使用处理程序列表来解决 promise 以调用已解决的状态(已完成或已拒绝)需要启动蹦床以运行 promise 作业(如果它尚未运行)。
    使用空堆栈启动蹦床执行的方法仅限于现有的浏览器 API,包括 setTimeout , setImmediateMutation Observer API .突变观察者 uses the microtask queue并且可能是引入它的原因(不确定确切的浏览器历史记录)。
    在事件循环接口(interface)的可能性中, setImmediate至少从未被 Mozilla 实现,根据 MDN,Mutation Observers 在 IE11 中可用,和 setTimeout在某些情况下会受到限制,因此即使延迟时间设置为零,执行回调也至少需要几毫秒。
    开发者大赛
    对于外部观察者来说,promise 库的开发人员相互竞争,看谁能在 promise 结算后以最快的时间开始执行 promise 处理程序。
    这看到了 setImmediate的介绍polyfills 根据浏览器中的可用内容,选择了从事件循环开始回调到蹦床的最快策略。 YuzuJS /setImmediate在 GitHub 上是这种 polyfill 及其 readme 的一个主要例子。非常值得一读。
    历史 在 ECMAScript 2015 中采用后
    Promise 包含在 ES6 中,但没有指定主机实现应该给予 promise 作业的优先级。
    YuzuJS/setImmediate作者上面的 polyfill 还向 TC39 委员会提交了一份意见书,以指定在 ECMAScript 中应优先考虑 promise 作业。该提交最终被拒绝,因为不属于语言标准的实现问题。支持提交的参数在 TC39's tracking site 上不可用|鉴于它没有引用被拒绝的提案。
    随后,HTML5 规范引入了浏览器中 Promise 实现的规则。 section on how to implement ECMAScipt's EnqueueJob abstract operation in host browsers指定它们进入微任务队列。

    答案

    What was the motivation for introducing the microtask queue? Why not just keep using the task queue for promises as well?


  • 微任务队列可能被引入以支持 Mutation Observer Events。
  • promise 库的早期开发人员找到了在微任务队列中输入作业的方法,并通过这样做最大限度地减少了解决 promise 和运行 promise react 作业之间的时间。在某种程度上,这在开发人员之间造成了竞争,但也有利于在处理完成一系列异步操作中的一个步骤后尽快继续异步程序操作。
  • 通过设计实现和拒绝处理程序可以添加到已经解决的 promise 中。如果出现这种情况,则无需等待某事发生即可继续进行 Promise 链的下一步。在这里使用微任务队列意味着下一个 promise 处理程序异步执行,具有干净的堆栈,或多或少立即。

  • 最终指定微任务队列的决定是由著名的开发人员和公司根据他们的专家意见做出的。虽然这可能是一个很好的选择,但这样做的绝对必要性是没有实际意义的。

    另见 Using microtasks in JavaScript with queueMicrotask()在 MDN 上。

    关于javascript - 引入一个单独的微任务队列的动机是什么,事件循环优先于任务队列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66190571/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com