When the code has been running for some time, the profiler thread eventually gathers enough data to decide which methods should be optimized. At that point,
Hydrogen and tries to optimize the resulting Hydrogen graph. This is where most optimizations happen. Most common optimizations are inlining and caching.
Once the Hydrogen graph is optimized, Crankshaft translates it to a lower-level representation called Lithium. Most of the Lithium implementation is architecture-specific.
Let’s review how event loop schedules resolved/rejected promises (including native JS promises, Q promises, and Bluebird promises) and next tick callbacks.
setTimeout, the main difference between libraries is what queue will be used to schedule the resolve and reject callbacks.
Therefore, it is quite clear that each unhandled promise is a potential problem delaying garbage collector from freeing memory. If references to the promise are kept around as well, we are going to leak the memory used by the promise object. Further, missing handlers break promise chains making the code unreliable.
Plugging Unhandled Promise Rejection
If you want to proof Node.JS applications against unhandled promise rejection, one of the simplest ways is by extending your code with the below:
Now, if there will ever be an unhandled promise in the code path, the application will crash providing us with a stacktrace. Using that trace, we could plug each leak, eventually getting to the point when all promises are handled correctly.
Although not strictly prohibited by the runtime, unhandled promise rejections cause memory leaks, among other problems and must be taken quite seriously. One simple way of dealing with unhandled exceptions is by crashing our code while gathering a stacktrace to identify the source of the problem.