简体   繁体   中英

Can setTimeout's delay argument be effected at all by sub-millisecond inputs?

I understand that setTimeout doesn't necessarily fire at the exact delay you specify, because there could be other items in queue at the instant that the timeout occurs and the engine will do those things first (further delaying the time you've specified).

However, I'm wondering if it does take sub-millisecond inputs into consideration at all. For example, if I input 1.12345678 ms, behind the scenes does it attempt to fire at that exact time, or does it parseInt the sub-millisecond value I've inputed before even truly setting the actual timeout (under the hood)?

Furthermore, let's say I'm determining the ms delay with long division and that division produces an exponent like 1.2237832530049438e-9 . Do I need to parseInt that exponent before handing it to setTimeout(()=>{},ms) or will setTimeout do the right thing (as long as it is some type of number) without me ever having to worry about prepping the input?

Update: Here's a snippet of setTimeout dealing with smaller and smaller sub-millisecond delay values:

 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);

Warning, the code above recurses 6,444 times in order to show that there comes a point where the timeOut value no longer gets smaller from dividing it further: after count 6440, the timeout sustains 2e-323 thereafter.

Modern browsers throttle setTimeout / setInterval calls to a minimum of once every 4 ms.

Also, MDN says that:

The delay argument is converted to a signed 32-bit integer. This effectively limits delay to 2147483647 ms, since it's specified as a signed integer in the IDL.

So, any fractions of milliseconds are not going to be effective.

The times are not JS specifications - they are specified in the DOM standards.

4 ms is specified by the HTML5 spec and is consistent across browsers released in 2010 and onward. Prior to (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), the minimum timeout value for nested timeouts was 10 ms.

However in Node JS , the timers used are the system-specific high precision timers. They (the system timers) can go in resolutions up to nanoseconds. It should be experimented in Node JS if the timer delays are saved as integers.

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);
}

According to source code for setTimeout it takes int as input. Which is a 32-bit signed integer.

So, the answer is, no. It does not takes into consideration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM