If you want to follow node idioms there are three patterns as Bruno said.
 They are:

Callback: I have an async, non-blocking operation that can take a while.  I
want to be notified when it finishes.  If there was an error instead of
throwing, the error will be passed to the first argument of the callback.
The callback is always the last argument in the original call.  The
callback will only fire one, but will always fire eventually. (Sometimes,
depending on your coding style, you can even add a constraint that the
callback never fires in the same tick the async function is called.  This
is usually done with a nextTick)  Callbacks are the async equivalent to a
normal function call that either returns a value or throws an error.

Event Emitter: I have some object that can emit events 0 or more times.
 These events may have different names too.  Maybe I want to allow multiple
consumers to pick and choose the data they are interested in.  If there is
an error, the event emitter will emit an "error" event.  If there are no
listeners to that event node will throw the error so that it doesn't go
undetected.

Stream: A stream is closer to a callback than an event emitter even though
it's implemented using Event Emitter.  A stream is some query that emits a
finite stream of data.  Usually this is text or binary data.  Streams are
meant to be used to pipe data between processes and sockets. where data
can't be shared via references and you don't want to buffer everything at
every point.  Streams have a very specific interface that involves
.write(), .end(), .pause(), .resume(), "drain", "data", "end" events and
more.  All the Stream prototype adds is a .pipe() function to readable
streams that makes it easy to pipe data from a readable stream to a
writable stream.  While a stream can also be used as a generic event
emitter, the primary reason for using the stream interface it to transport
a stream of homogeneous data that has a finite end between endpoints that
can't see each other directly.


Now I said these are the three node idioms.  Obviously, there are
also JavaScript idioms like the sync iterator callback in
Array.prototype.forEach.

Also I've been known to use vanilla callbacks that get called repeatedly
internally to some libraries for efficiency reasons.  When I write a
parser, for example, I usually write it as a simple function:

    function makeParser(onData) {
      ...
      return write(chunk) {
        .. when something is found
        onData(data)
      }
    }

I don't need an event emitter when all that's ever going to come out are
data events (this is a simple parser)  I just create a single closure.  But
this isn't a stream, if I want my parser to pause it's upstream data source
when whatever it's writing to is busy, I'll need to implement the stream
interface and have a lot more code. (Or the code using this parser can just
watch use the parser as a pure tool and create a stream itself that wraps
the parser)

There are many options, but since the question was about node idioms, they
are one-shot-callback last with err argument, event emitters, and finite
data streams.

On Sat, Apr 28, 2012 at 8:04 AM, Dominic Tarr <dominic.t...@gmail.com>wrote:

> @jorge
>
> exactly. that means that you callback both succeed and failed.
>
> On Sun, Apr 29, 2012 at 12:41 AM, Lothar Pfeiler
> <lpfei...@googlemail.com> wrote:
> > ... just clicked the send button too early.
> >
> > I use streams if the expected data is big and I want the memory
> > consumption to be low. Meaning, "Please interrupt me, and give me
> > small chunks, because I couldn't handle the big response".
> >
> > Lothar
> >
> > On Apr 28, 10:15 am, Lothar Pfeiler <lpfei...@googlemail.com> wrote:
> >> I understand the philosophy of using callbacks as "Please call me
> >> back, when the job is done". Meaning, call me back after calculating
> >> all prime numbers. (avoid roundtrips)
> >>
> >> I understand the event emitter philosophy as "Please interrupt me all
> >> the time you have news for me". Meaning, interrupt me for every single
> >> prime number. (lots of roundtrips, because I want to show the most
> >> current state all the time)
> >>
> >> So, a PrimeNumberGenerator could offer both versions for every
> >> purpose. And every single app might have a different understanding of
> >> the job size (or chunk size) and what are the news. So, the question
> >> for the app (which uses the PNG)  would be, whether it wants to act on
> >> every event or just act on a final result.
> >>
> >> Lothar
> >>
> >> On Apr 28, 6:20 am, Mark Hahn <m...@hahnca.com> wrote:
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >> > How can it be sugar?  It isn't compiled into anything else.  Sugar is
> part
> >> > of a syntax in a language.
> >>
> >> > You can call it whatever you want but it is a anonymous function
> being used
> >> > as a callback and passed to a node function that is called many times.
> >>
> >> > On Fri, Apr 27, 2012 at 8:57 PM, crypticswarm <crypticsw...@gmail.com
> >wrote:
> >>
> >> > > On Fri, Apr 27, 2012 at 10:40 PM, Mark Hahn <m...@hahnca.com>
> wrote:
> >>
> >> > >> >  I would say that in node calling a callback more than once is
> not only
> >> > >> discouraged, but forbidden, as if it were part of an implied, non
> written
> >> > >> contract.
> >>
> >> > >> Then how do you explain ...
> >>
> >> > >>     http.createServer(function (req, res) {
> >>
> >> > > http.createServer(function (req, res) {})
> >>
> >> > > is sugar for:
> >>
> >> > > http.createServer().on('request', function (req, res) {})
> >>
> >> > > --
> >> > > Job Board:http://jobs.nodejs.org/
> >> > > Posting guidelines:
> >> > >https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> >> > > You received this message because you are subscribed to the Google
> >> > > Groups "nodejs" group.
> >> > > To post to this group, send email to nodejs@googlegroups.com
> >> > > To unsubscribe from this group, send email to
> >> > > nodejs+unsubscr...@googlegroups.com
> >> > > For more options, visit this group at
> >> > >http://groups.google.com/group/nodejs?hl=en?hl=en
> >
> > --
> > Job Board: http://jobs.nodejs.org/
> > Posting guidelines:
> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> > You received this message because you are subscribed to the Google
> > Groups "nodejs" group.
> > To post to this group, send email to nodejs@googlegroups.com
> > To unsubscribe from this group, send email to
> > nodejs+unsubscr...@googlegroups.com
> > For more options, visit this group at
> > http://groups.google.com/group/nodejs?hl=en?hl=en
>
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines:
> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to nodejs@googlegroups.com
> To unsubscribe from this group, send email to
> nodejs+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en
>

-- 
Job Board: http://jobs.nodejs.org/
Posting guidelines: 
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nodejs@googlegroups.com
To unsubscribe from this group, send email to
nodejs+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

Reply via email to