The problem is that all these callbacks themselves take up memory and hold onto references in the V8 heap. And so if callbacks are being enqueued faster than they can be processed, the heap will get more full. V8's GC takes time proportional to the amount of live data, and so GCs will become more frequent and take longer. This further reduces the amount of available CPU time to process callbacks, which increases the amount of live data, until the system thrashes to a halt.
Haskell programmers (who use a similar scheduling mechanism for lazy evaluation) call this a "space leak", and it's a big problem in Haskell as well. The solution is for the runtime to let the calling code know that it's overloaded, and then either temporarily block the calling code from creating more callbacks until existing ones have run, or let the calling code gracefully degrade and choose to handle things in a simpler fashion.