2

这不仅仅是一个问题,它是一个保证Javascript超时功能的服务质量(QoS)的请求。

看下面的伪代码:

  .. start something in JS after a user action
  .. some js code
  setTimeout( function() { doSomething }, 1 );
  .. continue for longer than 1ms doing something
  .. end code for user action

  .. after 

  .. execute doSomething

我们能否确定在所有主流浏览器上,超时代码是在代码处理了第一个用户操作之后完成的?这与延迟时间无关。

延迟时间并不重要,而是在之后执行“doSomething”代码这一事实。

0延迟会发生什么?

提前感谢您在不同浏览器上的体验。

4

1 回答 1

4

由于 Javascript 的单线程特性,异步事件“触发”的时间与实际执行的时间不同。

正在评估的每个代码块在内部都表示为任务队列中的一个任务。因此,假设在给定代码块的中间,一个异步事件准备好通过setTimeout(). 如果延迟足够短,实际上在同一块代码的其余部分完成执行之前,没有什么能阻止它“触发”。然而,“触发”并不意味着setTimeout处理程序实际上会中断并执行。它只是意味着它变成了任务队列中的一个任务。实际执行仍然必须等到它从任务队列中弹出,并且在原始代码块完成之前不会发生。

这是一个 HTML5 规范片段,虽然不是对所有浏览器都具有权威性,当然是 HTML5,但只是说明性的:

http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#processing-model-3

在那里为主事件循环定义的 7 个步骤中的第一个是:

  1. 在事件循环的任务队列之一上运行最旧的任务,忽略关联文档未完全活动的任务 [...]

请注意,这第一步是原子的。该任务必须在环境重置和下一个任务被拾取之前运行完成。

还可以看看 John Resig 的帖子: http ://ejohn.org/blog/how-javascript-timers-work/

所以,写你的问题:

我们能否确定在所有主要浏览器上,超时代码都是在处理第一个用户操作的代码之后完成的。这与延迟时间无关。

……答案是肯定的,我们可以肯定。(在普通情况下......我假设我们只是在谈论传统的单/UI 线程,而不是在谈论 Web Workers 的处理)。

此外,尽管您确实提到您并不关心延迟时间本身,但您仍然可能有兴趣注意“钳制时间”(强制最小延迟),这似乎实际上是标准化的4毫秒

于 2012-10-04T08:55:46.217 回答