问题描述
我知道setTimeout不一定会按照您指定的确切延迟触发,因为在发生超时的瞬间队列中可能还有其他项目,引擎会首先执行这些操作(进一步延迟你的时间 指定)。
但是,我想知道是否确实考虑了毫秒以下的输入。例如,如果我输入了1.12345678
毫秒,它会在幕后尝试在该确切时间触发,或者是parseInt我在真正设置实际超时之前输入的亚毫秒值(在引擎盖下)?
此外,假设我要确定长除法的ms延迟,并且该除法会产生像1.2237832530049438e-9
这样的指数。我需要先parseInt
将该指数移交给setTimeout(()=>{},ms)
还是setTimeout
做正确的事情(只要是某种数字),而不必担心准备输入吗?
更新:以下是setTimeout的片段,用于处理越来越小的亚毫秒延迟值:
警告,上面的代码重复执行6,444次,以表明存在一个点,其中timeOut值不再进一步除以该值:在计数6440之后,此后超时持续2e-323
。
解决方法
现代浏览器将setTimeout
/ setInterval
调用每4毫秒限制一次。
此外,MDN表示:
delay参数将转换为带符号的32位整数。这个 有效地将延迟限制为2147483647 ms,因为将其指定为 IDL中的带符号整数。
因此,毫秒的任何小数点都不起作用。
时间不是JS规范-在DOM标准中指定。
4毫秒由HTML5规范指定,并且在各个浏览器中保持一致 在2010年及以后发行。之前的版本(Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2),嵌套超时的最小超时值为10 毫秒。
但是在Node JS中,使用的计时器是系统特定的高精度计时器。它们(系统计时器)的分辨率最高可以达到纳秒。如果计时器延迟保存为整数,则应在Node JS中进行试验。
,ExceptionOr<int> DOMWindow::setTimeout(JSC::JSGlobalObject& state,std::unique_ptr<ScheduledAction> action,int timeout,Vector<JSC::Strong<JSC::Unknown>>&& arguments)
{
auto* context = scriptExecutionContext();
if (!context)
return Exception { InvalidAccessError };
// FIXME: Should this check really happen here? Or should it happen when code is about to eval?
if (action->type() == ScheduledAction::Type::Code) {
if (!context->contentSecurityPolicy()->allowEval(&state))
return 0;
}
action->addArguments(WTFMove(arguments));
return DOMTimer::install(*context,WTFMove(action),Seconds::fromMilliseconds(timeout),true);
}
根据setTimeout
的源代码,它以int
作为输入。这是一个32位有符号整数。
所以,答案是不。它没有考虑。