【问题标题】:Asynchronous Promise blocking DOM异步 Promise 阻塞 DOM
【发布时间】:2018-12-31 16:49:09
【问题描述】:

异步 ​​Promise 在 React 中没有像我预期的那样工作(特别是 React,但我认为这将适用于其他场景)。他们似乎仍然阻塞了主线程,基本上冻结了我的浏览器。

我有这个处理按钮点击的方法:

onClick() {
  console.time('factorial')
  factorial(8000) // factorial is the culprit!
    .then(n => this.setState({ n }))
  console.endTime('factorial')
}

factorial 返回一个承诺,因此,正如预期的那样,我在控制台中得到了factorial: 2ms。但是,网页挂起。在查看性能指标时,这一点也很明显:

Promise 需要 700 多毫秒来评估,并且在整个持续时间内,DOM 似乎被阻塞了。这完全让我感到困惑,因为我希望 DOM 能够继续。如何让我的 factorial 函数不阻塞 DOM?

【问题讨论】:

  • 你能告诉我们你的factorial()函数是如何编码的吗?如果它只是运行一个大的同步循环,然后解决你绝对没有好处的承诺。为了允许其他事情与它的操作交错,它必须在计算周期之间将控制权实际返回给解释器。可以编写一个非阻塞的、协作的阶乘实现,但听起来你的实现不是那样的。此外,你表现得好像 DOM 是可以执行的东西。 DOM 是一种数据结构。那么也许您指的是一些特定的 DOM 事件或活动?
  • @jfriend00 我承认,我撒了谎。代码的实现不是阶乘,而是一个函数,其工作是生成波形。代码如下:pastebin.com/zBPMgM2h 是的,“阻止 DOM”,我的意思是没有执行任何 DOM 事件。我的错,我应该更具体一点。
  • 好吧,这里不包括真实信息(坦率地说,误导了我们),你没有得到尽可能好的答案,你基本上浪费了人们的时间。请用你的真实目标发布你的真实代码。当人们向我们展示真正的代码和真正的问题时,我们的效率至少提高了 10 倍。撰写问题的人经常将理论问题笼罩在错误的假设中,这使我们无法提供最好的帮助。
  • 您显然展示了一些假设的同步 factorial() 函数,该函数返回了一个承诺,这确实是基于一些错误的假设。这在现实世界中永远不会完成(同步函数没有理由返回承诺),因此使这个问题作为其他任何人的参考毫无用处。请贴出真实代码和真实问题。
  • 是的,这是一种流行的误解。您并不孤单,但在任何编程问题中,我们只能通过查看您的代码为您的情况提出最佳建议。它在这里并不自私——它具体而详细,对每个人都有帮助。

标签: javascript performance asynchronous dom promise


【解决方案1】:

异步函数不是线程。

它们在等待 JavaScript 事件循环之外的事情发生(如 HTTP 响应到达)时被暂停并置于后台。

当它们在运行时,它们仍在运行,并且像任何其他函数一样占用事件循环。

如果您想将某些处理分流到另一个线程,您需要使用Web Workers。 (至少在 Web 浏览器的上下文中;Node 有 Worker Threads)。

【讨论】:

    猜你喜欢
    • 2018-04-06
    • 2016-07-14
    • 1970-01-01
    • 2020-10-28
    • 2016-02-15
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 2012-10-14
    相关资源
    最近更新 更多