DEV Community

Discussion on: How Promises May Be Slowing Your App

Collapse
 
kiliankilmister profile image
Slick Kilmister

This really doesn’t give the promise it’s due. While the point “Sync Values, inside of Promises are only available Later” is probably something many new devs fall victim to, the final two points are simply trying to make a promise solve a problem they aren’t meant for.

A promise doesn’t try to be a stream. It’s just responsible for a single value. But multiple promises can easily create a stream. The used example is comparable to writing a function that returns an array and complaining that it doesn’t return an iterator.
Async Generators have been a builtin for years together with the for await...of syntax addition, and a promise based version of the Iterator/Iteration protocol stopped being a new idea long before that.

Promise cancellation is also something that in my doesn’t actually add much to its capabilities. The majority of times, a promise will represent something happening outside the control of the receiver (eg. a server request). A server processing what the promise represents will never never know that that promise has been declared as ‘cancelled’. Similarly some JS module would still have to actually implement the specific cancellation logic or it would run to the end regardless, making any kind of cancellation effectifly a no-op in most situations.
In addition to that, implementing a simple, but fully functional, cancelable promise is easy enough. Speculation is an npm package that was published over 4 years ago. It’s 50 lines of code (around 30 if comments and empty lines are removed) and that includes code for older browsers and edge-case handling.

But the best way to conserve processing resources when using promises is still:

“don’t start something unless you’re going to finish it”

The source of this problem usually isn’t that a promise can’t be canceled, but that promise returning functions are called to eagerly (this is a very smart joke, because promises are eager). Returning early when some condition is met and being a bit more conservative in dispatching requests will conserve resources much more effectively compared to boilerplating more complex solutions (like you mentioned: that’s what killed of the proposal).

Finally, while Observers/EventEmitters are amazing tools for a wide range of cases, the Promise is a perfect example of the unix principle: its purpose is to do one thing and do it well. It never attempted to be a solution for wide range of problems or facilitate complex exchanges, but it was always great as a small part of a larger solution for a problem.
Most observer implementations (including NodeJS Event emitters) are arguably the complete opposite of that (regarding the “one thing” part of course).
While NodeJS ‘events’ source code is amazingly pragmatic and contains very little, well designed code (the core of it is just shy of 800LoC), a library like rxjs contains many thousands of lines of code to implement its bulk of features (they have spent effort on optimizing that tho).
Removing excess bulk is a surefire way to get a performance increase. And coding in a pragmatic fashion is key to that.