8 Scheduling
This chapter covers
- Identifying the "unnamed monster" causing identical code to produce different results
- Tracing how runtime-specific task queues determine callback execution order
- Recognizing when the "drain until empty" rule starves your event loop
- Comparing scheduling APIs across multiple JavaScript runtimes
- Writing async code that depends on explicit ordering
So far we’ve covered how functions work, how objects hold state, and how errors propagate. Those are the building blocks. From here, we start looking at the mechanisms that coordinate them across time.
Back when I was consulting with customers to help them identify performance bottlenecks and bugs in their Node.js applications, I would typically lead the conversation with a question: is your application using Promises? If they said yes, without even looking at the code first I’d make an assertion that would often catch them off guard: “If you’re using promises, you’re likely using them wrong”.
At first glance, this seems a bold and potentially arrogant assertion, and I’ve had quite a few engineering teams rightfully push back on it. What I’ve learned, however, is that while most developers understand what promises are used for, they tend to skip over how they work and how they interact with other parts of the application, and it is that gap that often leads to problems.