Hacker News new | past | comments | ask | show | jobs | submit login

Promise was clearly necessary, because without it we had hundreds of other less principled ways to implement async control flow :)



We had, and still prefer (looking at npm stats) the async module. Eg:

    promise.then(function(){}).then(function(){}) 
is not substantially different than:

    async.waterfall([function(){}, function(){}])
Promise advocates kept pretending async didn't exist though, and everybody was using callback hell.


There's a lot of old cruft using async (my current workplace being one of them) - bluebird also has 4x the downloads of async.

async is pretty terrible though, you cannot pass the results from one execution to another, i.e. passing results from one function in async.series to another, which results in developers tending to pollute variable scope by defining above and filling it in inside each callback. This prevents the ability to write clean isolated testable functions.


You can return the first from a function and it will be a promise. Promises are reusable. Also they contain exceptions in their context. Those can be handled at any point of the promise-chain.

So promises are way more composable than callback based solutions.


Nobody pretended that async didn't exist, we just knew its the best "solution" that ignored the problem.

Which was: throwing away the entire language's compositional features, including the concept of input arguments and return values, results with... poor compositionality, of course.


I thought the problem was callback hell. I've sat through a bunch of promise talks and the problem was never 'JS should be more compositional'.


Yes, uncompositionality of callbacks leads to callback hell. Or to reinventing every single thing but for callbacks. Like array.map (which works with promises) or array.forEach (also works with promises) or every single synchronous function (they all work when passed to promises).


If you solve callback hell for a series of sequential functions by using an actual series of sequential functions, you don't have nested callbacks and you didn't require Promises or composition - just a basic understanding of data structures and first class functions.

It seems you're defining callback hell as 'whatever promises solves' rather than it's common definition of over-nesting.


Callback hell is a "loss of composition" problem. Most languages, including JavaScript, have things called expressions. Expressions rely on functions returning their output. They become useless when functions give their output through a callback passed as their input: they don't compose with that frankenstein.

Node style callbacks are a prime example of how in the quest for "simplicity" and hate for abstractions its easy to build a monster / frankenstein like caolan's async. Node callbacks were a self-contradicting philosophy: it abandoned all thats already in the language in the quest to avoid an abstraction that was not already in the language :)


Hrm, it's always seemed natural (and not frankenstein) that a function would be input as much as a number or string is. 'My name is Steve, my age is 7, and here's what do to one the database has saved'.

That said I see how the inconsistency you're talking about with how expressions return values with callbacks and you've certainly put the point very well.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: