Posted almost 2 years ago. Visible to the public. Repeats.

Your browser might silently change setTimeout(f, 0) to setTimeout(f, 5)

When you're nesting setTimeout(f, 0) calls, your browser will silently increase the delay to 5 milliseconds after the fourth level of nesting. This is called "timeout clamping".

Deeply nested setTimeout can happen when you're using a non-native Promise polyfill with long chains of then calls.
The native Promise implementation (Can I use link) uses microtasks and is thus not subject to timeout clamping.

If you need short nested timeouts, you can use an setImmediate polyfill. This employs various hacks to give you access to the microtask queue.

Measuring timeout clamping

Here is a deeply nested setTimeout call:

Copy
var start = Date.now(); function printElapsed() { var now = Date.now(); console.log(now - start); } setTimeout(function() { printElapsed(); setTimeout(function() { printElapsed(); setTimeout(function() { printElapsed(); setTimeout(function() { printElapsed(); setTimeout(function() { printElapsed(); setTimeout(function() { printElapsed(); setTimeout(function() { printElapsed(); setTimeout(function() { printElapsed(); setTimeout(function() { printElapsed(); setTimeout(function() { printElapsed(); setTimeout(function() { printElapsed(); }, 0); }, 0); }, 0); }, 0); }, 0); }, 0); }, 0); }, 0); }, 0); }, 0); }, 0);

This yields the following messages:

Copy
2 3 5 6 11 16 20 25 29 33 38

Observe how after 6 the time difference jumps from 2 to 5 milliseconds.

Growing Rails Applications in Practice
Check out our new e-book:
Learn to structure large Ruby on Rails codebases with the tools you already know and love.

Owner of this card:

Avatar
Henning Koch
Last edit:
almost 2 years ago
by Henning Koch
Keywords:
async, asynchronous
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Henning Koch to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more