

Promises/A+ - Dekku
http://promisesaplus.com/

======
domenicd
It's worth noting we are _very_ close to finishing up a 1.1 revision of the
spec, which clarifies a few things mainly around how promise libraries
interoperate with each other's promises. You can find the work in our master
branch (as opposed to gh-pages):

[https://github.com/promises-aplus/promises-spec](https://github.com/promises-
aplus/promises-spec)

Including a changelog:

[https://github.com/promises-aplus/promises-
spec/blob/master/...](https://github.com/promises-aplus/promises-
spec/blob/master/changelog.md)

And the issues still open versus closed in the 1.1 timeframe are at

[https://github.com/promises-aplus/promises-
spec/issues?miles...](https://github.com/promises-aplus/promises-
spec/issues?milestone=2&page=1&state=open)

We were hoping to do a revision of the website's look at the time of the 1.1
release as well, mainly adding links to additional resources in the repository
(like the implementations list, credits, etc.). A bit sad that we haven't
moved fast enough to finish that before making the front page of Hacker News!

------
SeanDav
I have just started doing development in Node.js. Originally using the
excellent caolan/async library
([https://github.com/caolan/async](https://github.com/caolan/async)) for
handling synchronous situations. Now started moving towards Promises but
finding it quite hard to locate any "Promises for Dummies" type guide. Most of
the libraries like "q" etc
([https://github.com/kriskowal/q](https://github.com/kriskowal/q)) just give
you a list of functions to use and related syntax but I have yet to come
across a guide that goes into detail as to exactly how and why you use certain
functions.

I am kind of figuring things out as I go along but if anyone here can point me
to such guides, I would be most grateful.

~~~
domenicd
I have given several talks, for which slide decks and one video are available:

[http://www.slideshare.net/domenicdenicola/callbacks-
promises...](http://www.slideshare.net/domenicdenicola/callbacks-promises-and-
coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript)

[http://www.slideshare.net/domenicdenicola/promises-
promises](http://www.slideshare.net/domenicdenicola/promises-promises) with
video at
[http://www.youtube.com/watch?v=MNxnHbyzhuo](http://www.youtube.com/watch?v=MNxnHbyzhuo)

[http://www.slideshare.net/domenicdenicola/boom-promisesa-
was...](http://www.slideshare.net/domenicdenicola/boom-promisesa-was-born)
which is more inspirational and motivational than practical

Otherwise, in the Q readme we try for a "graduated tutorial" approach; would
welcome any feedback you have to make it more friendly. We try to relegate the
"list of functions" to the API reference at
[https://github.com/kriskowal/q/wiki/API-
Reference](https://github.com/kriskowal/q/wiki/API-Reference)

~~~
SeanDav
Hi Domenic, Thanks for those links - I will check them all. There is another
one of yours (co-speaker) that I thought was excellent: Redemption from
Callback Hell
([http://www.youtube.com/watch?v=hf1T_AONQJU](http://www.youtube.com/watch?v=hf1T_AONQJU))

~~~
domenicd
Oh yes, I always forget about this one because it's not on my SlideShare, but
you're right, it's really excellent! Michael did a great job putting that
together and I was honored he invited me to share the stage.

------
_greim_
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](https://github.com/greim/await.js)

~~~
drhayes9
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](https://github.com/kriskowal/q#combination)

~~~
_greim_
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.

~~~
jkrems
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).

------
tjansen
The great thing about Promises/A+ is that it's so small. I have implemented it
in 375 bytes, and was even able to add two convenience functions:
[https://github.com/timjansen/PinkySwear.js](https://github.com/timjansen/PinkySwear.js)

~~~
scotth
Great project name.

------
domenicd
I gave a talk at JSConf US 2013 about the genesis of this spec, and how I
believe it plays into the future of open, developer-driven APIs for the web
platform. I hope the video is up soon, but until then, the slides are at
[http://www.slideshare.net/domenicdenicola/boom-promisesa-
was...](http://www.slideshare.net/domenicdenicola/boom-promisesa-was-born)

------
martingordon
Maybe I'm missing something, but I find C#'s async/await much more intuitive
(not having written any C# and currently working on a pet project using
promises with Node and Q).

My issue with promises is that I find myself working around the API/language
when I actually want synchronous code. My app calls a JSON API and then writes
the results to three tables (in sequence). In "normal", blocking code:

    
    
      results = getResults(); writeTable1(results.foo); writeTable2(results.bar); writeTable3(results.baz);
    

Using Node and Q:

    
    
      db.load().then(()-> setupDB(db)).then(()-> collectData(db)).done()
    

In which setupDB() returns a chain of three promises and collectData, which
loops through the results and attach a new promise to the chain in order to
return a chain of `n` promises.

Are these just growing pains of learning a new paradigm or am I using the
wrong tool for the job?

Can someone point me to any projects that actually use promises?

~~~
domenicd
It's worth noting that C#'s async/await is based directly on promises; they
are called `Task<T>` in .NET. Indeed, they share a common ancestor I believe;
.NET 4.5's `Task<T>` is derived from F#'s `Async<T>`, and both `Async<T>` and
JavaScript promises are based on E's promises.

~~~
martingordon
Yeah, I think the big difference for me is the language support. You can just
await a method call instead of having to wrap the remainder of your block in a
function.

Perhaps I should look into IcedCoffeeScript ([http://maxtaco.github.io/coffee-
script/](http://maxtaco.github.io/coffee-script/)) instead of plain CS.

------
kolodny
I wrote a library a while ago that nearly fulfills this entire spec. I've
added/changed things that I thought were more intuitive.
[https://github.com/kolodny/wttt](https://github.com/kolodny/wttt)

~~~
jkrems
The point of having the spec is that libraries can freely exchange data and
promises, even if they depend on totally different flow control libraries,
while still being certain that error handling and chaining works as expected.
It looks like if I build on top of your library, I'm locked in.

This is not to say that it invalidates your library or that every promise
library has to comply to A+ or that A+ is the only good way to design promises
in JS.

------
willvarfar
> 3.2.1.1 If onFulfilled is not a function, it must be ignored.

This is idiomatic JS I guess, but it bugs me to bits. IMO the parameter should
be a function or it should be null; anything else should throw an error.

~~~
domenicd
`then` is meant to return a promise, i.e. return an asynchronous value; it
should never synchronously throw an error.

That said, I somewhat agree (although in JavaScript it should be `undefined`,
not `null`). If we were starting clean, instead of with tons of code in the
wild that did `.then(null, onRejected)` or `.then(false, onRejected)`, we
would have the resulting promise be rejected with a `TypeError` if
`onFulfilled` was neither `undefined` nor a function.

~~~
willvarfar
Hmm null is easier to pass on purpose and undefined is easier to pass by
accident.

Sending in undefined for a non-trailing argument takes effort.

I think the literal null is far more communicative of the developers intent.

But the general point is, JS APIs tend to fail silently on error by design and
that's something that bugs me, literally. Bugs. Lots of them.

I agree regards returning a failure rather than throwing an exception, though.

------
unwiredben
Thanks for this discussion... after reading Domenic's slides, watching his
talk, and going through the questions here and on the gist, I've filed a bug
to try to move Enyo's async implementation to promises after our next release.
([https://enyojs.atlassian.net/browse/ENYO-2700](https://enyojs.atlassian.net/browse/ENYO-2700))
Currently, our code is more like the jQuery 1.5 implementation, but it really
lacks the nice error semantics that Promises/A+ has.

------
andrewcooke
wouldn't it be good to explain somewhere, early on, that this is for
javascript?

~~~
domenicd
This is actually a really good point, haha! Filed, and will fix in the
upcoming so-close-to-done 1.1 revision: [https://github.com/promises-
aplus/promises-spec/issues/135](https://github.com/promises-aplus/promises-
spec/issues/135)

------
ricardobeat
Promises are coming of age too late, and still have unsolved fundamental
issues.

Meanwhile, ES6 generators are coming to node v0.12, already in FF and soon to
be in Chrome; _that_ is a whole different game.

~~~
1st1
It's still better to use promises as an underlying mechanism, so that you can
"yield* promise" or "yield* generator". This approach is now implemented in
python tulip framework, and it solves the problem of combining the existing
callback-based code with coroutines.

------
pspeter3
Just out of curiosity, why don't we use node's event emitters to wrap
callbacks as promises?

~~~
jkrems
Because promises resolve to one value which can be retrieved long after the
promise was resolved. This is a fundamentally different approach than
EventEmitters. node's streams are the closest thing to "promise meets event
emitter" I'm aware of. But maybe I'm missing the point of your question.

