
Sane Async Patterns in JavaScript - hijonathan
http://www.slideshare.net/TrevorBurnham/sane-async-patterns/
======
quarterto

      Next time you're about to define a function with a callback argument, don't.
    

No, do. It's the prevailing style in Node.js and elsewhere, and so there exist
tools to transform them (syntactically or otherwise) into more palpable
styles:

<https://github.com/0ctave/node-sync> <https://github.com/BYVoid/continuation>
<https://github.com/JeffreyZhao/wind> <https://github.com/Sage/streamlinejs>

~~~
joshguthrie
I already knew about node-sync, but continuation really brings something new.
I'll check the source to understand what it does under the hood.

~~~
j_s
Also, the comparison on the project's README is informative (and lists
additional options):

<https://github.com/BYVoid/continuation#relevant-projects>

------
dap
It's an interesting presentation, but it neglects an obvious solution to the
nested callbacks problem, which are the various "async"-like control-flow
libraries out there. More importantly, it neglects a critical problem with all
of these approaches, which is being able to _observe_ asynchronous state (from
a debugger, repl, or whatever) when things go wrong -- when a callback (or
event) you expected doesn't fire, or the same one is called (or emitted) early
or too many times. IME, these are the really hard problems to debug in async
JavaScript, and there are improvements available (I wrote node-vasync for
this), but I still wouldn't say it's well solved by any of these approaches.

~~~
craigyk
Agreed. I think I saw that async in C# has exceptions that behave as one
naively expects they should. That would make JS so much more awesome, even
with callbacks. The worst part of them isn't the pyramid, IMO, so much as they
all the horrible repeated "if error...."

------
mtdewcmu
"Nested spaghetti" strikes me as a mixed metaphor. I'd have to ask an expert
on Italian cuisine, but I don't think spaghetti nests. Literary aspects aside,
I don't think the "pyramid of doom" is what is meant by spaghetti. In the
pyramid, it's easy to see the sequence in which things happen. In spaghetti
code, it's hard to see the sequence -- that's the problem.

The fact that the pyramid makes it easy to see the sequence, i.e. follow the
chain of causation, and easy to find the callbacks, argues that there is a
place for it. Additionally, it makes it easy to transfer state through the
chain, since each callback has access to the previous one's variables.

The other patterns, which probably all have appropriate uses, too, would seem
to carry a greater risk of spaghetti -- i.e. control that jumps around
unexpectedly and is hard to follow.

~~~
IgorPartola
It's easy to see what's happening if everything is written in one file. It's
hard if your callback are fired from and/or go into minimized library code you
don't control or don't want to debug. You may have your own pyramid, but it's
really sitting on someone else's pyramid.

------
xpaulbettsx
This "PubSub" pattern is really trying to recreate RxJS but without the
expressiveness - if you find yourself doing this kind of work a lot, you
should check it out

<http://reactive-extensions.github.com/RxJS>

<https://github.com/Reactive-Extensions/RxJS>

~~~
jlogsdon
PubSub is pre-node, making RxJS a "more expressive" PubSub.

------
stefantalpalaru
Dear title-editing moderators: the "in javascript" part was relevant.

------
koko775
These patterns apply to Javascript, which I wasn't expecting from the title.
Mods, could you edit in "Javascript" somewhere in the title, please?

------
Silhouette
IME, most clutter from async logic in JavaScript, however it's dressed up,
only happens at all because of implementing something that is fundamentally
sequential and synchronous using the wrong tools for the job. The slide "A JS-
er's lament" was a great demonstration of how fundamentally broken the current
JS model is.

Put another way, the obviously missing pattern to me is to just move the
concurrency up to the level of having multiple threads, and then use
synchronous interfaces for synchronous operations. Now that Web Workers are
starting to become more widely supported, I don't understand why we aren't
heading for synchronous APIs as fast as humanly possible.

------
33a
The bit about AMD didn't really fit in with the rest. Why start talking about
module loading when you were discussing async earlier? They are completely
separate issues.

------
jgreen10
Have you tried state machines?

My JS programming often looks something like:
<https://gist.github.com/anonymous/5314313>

I don't really care if the APIs I use have callbacks or promises, both fit in
just fine.

~~~
Groxx
Nice example :) I tend to think state machines are underused, they give you
wonderfully predictable behavior.

------
Offler
The sooner we get Generator support everywhere the better so we can start
using <http://taskjs.org/> and stop talking about these issues.

------
skylan_q
While looking through the slides, I was wondering:

Is there some community-standard way of naming/declaring a JS function to let
the programmer know just by reading the function's name that it will return a
promise instead of a final computed value? I'm interested in knowing how
people handle this. It's easy to forget that a function doesn't return a
promise if the function name makes no mention of it, so I just make it
explicit in the function name... but that's just how I handle it.

~~~
tantalor
Functions should be documented with the types of their parameters and return
value.

~~~
skylan_q
I suppose I've just learned to really appreciate the "?" and "!" at the end of
ruby function names...

------
loganb
Promises are about as clean as you can get in a purely async environment.

Yet, notice how no one shows off how easy it is to write a loop. Oh, and what
happens when your code throws an exception? It's as though that path halted
forever.

Also, what happens when you have a method defined as

result = foo(args);

that now needs to perform an async operation? Enjoy refactoring every call
site.

------
potch
Sometimes require.js feels a bit heavy for what is mostly a straightforward
concept (AMD), so I use a _much_ simplified version of the pattern:
<https://gist.github.com/potch/4156519>

------
purplelobster
I'm new to js and using async.js on the client and node server. Is that
acceptable? Honestly I just dont find promises very intuitive.

------
craigyk
That twitter quote is pretty funny.

------
chris_mahan
slideshare.net is blocked at the office.

