Don't Over-Promise (a pun & a parable)
In Blog Post Number One, I referred to the Zen of Python's rules for keeping things simple, readable, explainable.
That all seems simple, easy to repeat, good advice to avoid endless mindloops. But it's easily forgotten when there are many concerns or people to address as the number of communications becomes combinatoric.
Consider the ES6 es-discuss debates regarding Futures/Promises
start here.
The threads go on for several days, the parties trying to hammer out the nuances
of a serviceable API for Futures/Promises, based on Promises/A, Promises/A+
(then-ables), JQuery already-in-the-wild Deferred/Promises, etc.
And that's just the syntax and semantics of Promises to be supported natively in the next big iteration of JavaScript.
On the implementation side, James Coglan argues in a lengthy essay that the Node.js team missed the boat when they evicted Promise implementations from the Node.js core. Yet the lengthy comments and code examples demonstrate how hard it is to understand when not to use Promises (e.g., "promises try to solve the wrong problem", "the confusion comes from the attempt to use promises to control flow of statements, not dependencies on values").
Drew Crawford argues in Broken Promises, that Promises are not a general solution but best applied to specific situations, because, for example, "a great number of perfectly ordinary things depend on knowing how many elements there are." Trouble arises when the number of elements now or in future is undetermined. Drew mentions several problems that must be addressed by Futures/Promises libraries - memory, composability, parallelization and atomicity. After walking through these he has created a new DSL "to specify control flow and timing information" – all things which the language already does for you… (then came enlightenment)
The Node.js team's decision, then, is not a vote against Promises, but a vote to keep things simple in the core and let harder issues be sorted out in userland.
If it is hard just to understand the problem, the solution will more than likely be hard to explain. If the implementation is hard to explain, it's a bad idea.