News for hackers. Stuff that matters.
Re:Promises/A+ by _greim_ on Monday July 08, 2013 @04:04PM (#6008927)
My beef with JS Promises (uppercase "P") is that, as a programming idiom, I prefer once I have X, Y and Z, do something with X, Y and Z over get X, then get Y, then get Z. In the former case, the provisioning logic is a separate concern; it could be done in parallel, serially, or via some combination of both. In the latter case, it's inherently serial.

I wrote an alternate implementation of promises in JS (lowercase "p") that uses the former approach: https://github.com/greim/await.js

Re:Promises/A+ by tlrobinson on Monday July 08, 2013 @04:45PM (#6009166)
It's absolutely possible to do multiple things in parallel using Promises/A(+) then "resolve" a new promise once they're all done. That's what Q.all() in the Q library does, for example.

That API isn't written into the Promises/A+ spec because it doesn't need to be. That spec is the minimal things necessary for multiple promise implementations to be interoperable.

Re:Promises/A+ by ufo on Monday July 08, 2013 @04:31PM (#6009087)
Personally, that sounds like a really odd complaint to make. After all, running promises in parallel should be just a matter of using a simple library function that you can very easily code yourself if its not already provided.

I tend to find that the biggest problem with promise libraries is writing code with lots of jumps and more advanced control flow. If you are using an explicit continuation-based approach then doing a jump (for a loop or for breaking out early) is just a matter of calling the appropriate continuation. On the other hand, promises naturally tend to prefer the sort of code where there is only a single return statement at the end (unless you abuse the error handling system but there are all sort of problems if you do that)

Re:Promises/A+ by drhayes9 on Monday July 08, 2013 @04:29PM (#6009073)
I don't understand your comment (or this is related to the lack of good introductory material noted in another comment).

You can retrieve the results of promises in parallel, serially, or via some combination of both. That's part of their power versus straight callbacks which enforce a serial approach.

Check out this link to q's documentation: https://github.com/kriskowal/q#combination

Re:Promises/A+ by ufo on Monday July 08, 2013 @04:35PM (#6009112)
TBH, both callbacks and promises are kind of similar when it comes to running things in parallel. In both cases you use the same sort of semaphore pattern and its something thats easy to hide behind a library function.

    function parallelCallbacks(cbs, onAllDone){
        var nLeft = cbs.length;
        var results = []
        var onOneDone = function(res){
           results.push(res);
           nLeft -= 1;
           if(nLeft <= 0){ onAllDone(results) }
        }

        for(var i=0; i<cbs.length; i++){
            cbs[i](onOneDone);
        }
    }

    parallelPromises([
       function(){ return promise(10) },
       function(){ return promise(20) }
    ).then(function(results){ ... });

    parallelCallbacks([
        function(onDone){ onDone(10) },
        function(onDone){ onDone(20) }
    ], function(results){
       ...
    });
Re:Promises/A+ by tlrobinson on Monday July 08, 2013 @04:49PM (#6009184)
One of the main differences is in error handling. Much like exceptions, errors are automatically propagated to the first error handler in the promise chain. With Node-style callbacks you need to explicitly check for errors and re-emit them at every stage.

I also think promises' use of return values vs passing a callback as an argument is conceptually cleaner and easier to compose.

Re:Promises/A+ by ufo on Monday July 08, 2013 @05:00PM (#6009263)
Absolutely correct, I ommited error handling to keeop the example simple but error handling is definitely more natural in a promise setting because you don't need to make your own error callback protocol.

That said, I still feel that both promises and explicit callbacks kind of suck in their own way. Callback code is usually much more verbose and has bad error handling while promises are bad at "jumpy" control flow. When I last worked in a big JS project it got bad enough that I eventually wrote my own control flow library on top of the base Dojo promises we were using so nowadays if I had to work with a big JS project again I would definitely try to use of those tools that add async control flow to the language and compile doen to regular continuations (looks nice like promises, can use loops, break and return like regular JS and raw callbacks don't need extra runtime support)

Re:Promises/A+ by _greim_ on Monday July 08, 2013 @06:04PM (#6009663)
My main point is that Promises don't have any concept of parallelism; all() is specific to the Q library, not part of Promises/A+. Obviously that's the intent—low-level building blocks—but it leaves one feeling like Promises don't actually solve any hard problems. You still have to solve them yourself.
Re:Promises/A+ by jkrems on Monday July 08, 2013 @10:08PM (#6010665)
Promises/A+ is not a promise library. It's not a spec about "what should a promise library do". It's about interoperability - "how can I exchange data AND promises between libraries without relying on a shared library/on everyone using the same library for flow control?". Also the spec makes error handling non-surprising, I don't need to read through the docs of a library to know how errors propagate. It looks like your promise library would have been easy to make comply with the spec by just calling "onkeep" "then" (and maybe adapting a few minor details).
Re:Promises/A+ by ufo on Monday July 08, 2013 @09:39PM (#6010574)
But callbacks also don't have any concept of paralelism and its trivially easy to code all() yourself once and then forget about it.

The hard problem that promises solve are

1. Its more similar to regular code versus explicit CPS (no pyramid of doom, use "return" to return values, can store promises in data structures or pass them around to other functions)

2. Error handling. Regular Javascript has try-catch blocks for exception handling but those don't work with async code. Promises let you use exceptions in async code without having to worry about error callbacks.

Re:Promises/A+ by andywhite37 on Monday July 08, 2013 @04:34PM (#6009105)
I like your approach with your await library. You're probably aware of this, but the jQuery "Deferred" implementation of promises has a similar mechanism that I'm not sure is common in other JavaScript promise implementations:

$.when()

http://api.jquery.com/jQuery.when/

Re:Promises/A+ by jasondenizac on Monday July 08, 2013 @04:48PM (#6009182)
Q has `Q.all()` which does the same thing: https://github.com/kriskowal/q/wiki/API-Reference#promiseall
Re:Promises/A+ by andywhite37 on Monday July 08, 2013 @05:44PM (#6009544)
Oh that's cool, thanks for the reply. I haven't looked at Q yet, but I've heard a lot about it. I guess it's time to have a look.