javascript - Javascript事件循环任务队列可能溢出吗?

标签 javascript asynchronous event-loop scala.js monifu

是否可以定义一个不应跨越的边界,以便应用程序在任务调度(过度)使用方面能够很好地扩展?

问题:

  1. 执行 setTimeout 是否有一定的成本?比方说 0.1ms 或 CPU 时间?与在不同环境中生成线程相比,成本肯定要低几个数量级。但有吗?
  2. 对于需要 1-2 毫秒的微任务,是否最好避免使用 setTimout?
  3. 有什么不喜欢安排的事情吗?例如,我注意到在安排存储检索和其他事情时,IndexedDb 会出现某种写锁饥饿
  4. 可以安全地安排 DOM 操作吗?

我这么问是因为我开始使用 Scala.js和 Rx 实现 Monifu即大规模使用调度。有时一行代码会向事件循环的队列提交 5 个任务,所以基本上我会问自己,是否有类似任务队列溢出之类的东西会降低性能?我问这个问题尤其是在运行测试套件时,每秒可能有数百个任务排队。

这引出了另一个问题,是否可以列出何时应使用 RunNow/Trampoline 调度程序以及何时应使用与 Rx 有关的队列/异步调度程序的情况?每次我写类似 obs.buffer(3).last.flatMap{..} 这样的东西时,我都会想知道这个问题。它本身调度多个任务

最佳答案

关于 Monifu 中调度的一些注意事项 - Monifu 尝试崩溃异步管道,因此如果下游观察者本质上是同步的,那么 Monifu 将避免将任务发送到调度程序中。 Monifu 还具有背压功能,因此它控制有多少任务提交到调度程序中,因此您不会最终遇到浏览器队列爆炸的情况。

例如,像这样... Observable.range(0,1000).foldLeft(0)(_+_).map(_ + 10).filter(_ % 2 == 0) 仅在调度程序中发送单个任务以启动初始循环,否则,如果观察者也是同步的,则整个管道是完全同步的,并且不应在该队列中发送任何其他任务。它发送队列中的第一个任务,因为它不知道该源有多大,并且通常订阅数据源是与您不想阻止的某些 UI 更新相关的。

有 3 个较大的异常(exception):

  1. 您使用的数据源不支持背压(例如网络套接字连接)
  2. 您在接收方(即观察者)中有一个真正的异步边界,例如在与外部服务通信时可能会发生这种情况,并且这是一个您不知道何时完成的真正的 Future

一些可能的解决方案...

  1. 如果服务器通信不支持背压,在这种情况下,最简单的事情就是修改服务器以支持它 - 而且,正常的 HTTP 请求自然是背压的(即,它就像Observable.interval(3.秒).flatMap(_ => httpRequest("..."))
  2. 如果这不是一个选项,Monifu 有缓冲策略...所以你可以有一个无界队列,但你也可以有一个触发缓冲区溢出并关闭连接的队列,或者尝试进行背压的缓冲,您还可以在缓冲区已满时开始删除新事件,我正在研究另一种缓冲策略来删除旧事件 - 目的是避免队列耗尽
  3. 如果您对无限个源使用“合并”,则不要这样做;-)
  4. 如果您正在向外部服务发出请求,请尝试优化这些请求 - 例如,如果您想通过将事件发送到网络服务来跟踪事件的历史记录,则可以对数据进行分组并执行批量请求等<

顺便说一句 - 关于浏览器端和任务调度的问题,我担心的一件事是 Monifu 不能足够有效地中断工作。换句话说,它可能应该将较长的同步循环分解为较小的循环,因为比性能问题更糟糕的是 UI 中可见的延迟问题,因为某些循环阻止了 UI 更新。我宁愿将多个较小的任务提交给调度程序,而不是一个较大的任务。在浏览器中基本上有 cooperative multi-tasking ,一切都在同一个线程上完成,包括 UI 更新,这意味着让某些工作阻塞该线程太长时间是一个非常糟糕的主意。

也就是说,我现在正在优化并更加关注 Javascript 运行时。在 setTimeout 上使用它是因为它比 setImmediate 更标准,不过我会在这些方面做一些工作。

但是,如果您有性能很差的具体示例,请传达它们,因为大多数问题都可以解决。

干杯,

关于javascript - Javascript事件循环任务队列可能溢出吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27305747/

相关文章:

javascript - 如何使 Mongoose 不将空数组或对象字段插入文档中

javascript - 使用 UI Utils 进行 Angular 表单验证

c# - 当多个并行线程等待同一个 Task 实例然后抛出时会发生什么?

sockets - httplistener异步和同步的区别

javascript - React/Axios api 调用返回 Promise

python - 什么是 event_loop_policy,为什么在 python asyncio 中需要它?

javascript - jQuery - 动态改变 CSS

javascript - 将 div 标签更改为 IE7 的表格

javascript - NodeJs-事件循环只处理 I/O 请求吗?

javascript - nodejs(libuv)事件循环是否在一个阶段(队列)中执行所有回调,然后再移动到下一个阶段或以循环方式运行?