setTimeout 的延迟参数可以通过亚毫秒级输入来影响吗?



我知道setTimeout不一定在您指定的确切延迟时触发,因为在超时发生的那一刻,队列中可能还有其他项目,引擎将首先执行这些操作(进一步延迟指定(。

然而,我想知道它是否真的考虑了亚毫秒的输入。例如,如果我输入1.12345678ms,在幕后它是试图在那个确切的时间触发,还是在真正设置实际超时之前(在引擎盖下(解析我输入的亚毫秒值?

此外,假设我用长除法确定ms延迟,该除法产生类似1.2237832530049438e-9的指数。在将指数交给setTimeout(()=>{},ms)之前,我需要parseInt吗?还是setTimeout会做正确的事情(只要它是某种类型的数字(而不必担心准备输入?

更新:以下是setTimeout处理越来越小的亚毫秒延迟值的片段:

let count = 0;
function consoleLog(timeOut)
{
let now = Date.now();
timeOut = (timeOut / 1.12345);
setTimeout(()=>
{
count += 1;
if (count <= 6444)
{
console.log(`Timestamp ${now}`,`Timeout: ${timeOut}`,`Count: ${count}`);
consoleLog(timeOut);
}
});
}
consoleLog(1000);

警告,上面的代码重复了6444次,以表明timeOut值不再因进一步除以而变小:在计数6440之后,超时将维持2e-323

现代浏览器将setTimeout/setInterval调用限制为至少每4毫秒一次。

此外,MDN表示:

延迟参数转换为带符号的32位整数。这有效地将延迟限制为2147483647毫秒,因为它被指定为IDL中的带符号整数。

因此,任何毫秒的分数都不会有效。

时间不是JS规范,而是在DOM标准中指定的。

4ms由HTML5规范指定,并且在浏览器之间是一致的2010年及以后发行。之前的版本(Firefox 5.0/Thunderbird 5.0/SeaMonkey 2.2(,嵌套超时的最小超时值为10ms

但是,在Node JS中,使用的计时器是系统特定的高精度计时器。它们(系统计时器(的分辨率可以达到纳秒。如果定时器延迟保存为整数,则应该在NodeJS中进行实验。

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位有符号整数。

所以,答案是否定的。它没有考虑到这一点。

最新更新