This is actually much more simple than you're all making it.  The
Node.js API is remarkably consistent on this point.

1. Callback

A callback is for cases where you have a single "question", which will
be answered by either an error, or optionally some data.

getSomeThing(arg, arg, arg, function (er, someThing) {
  if (er) return ohnoes(er)
  // .. now do something with the someThing
})

Callbacks should be called *exactly* once.

2. EventEmitter

EventEmitter : Callback :: Class : Function

An EventEmitter is used in cases where a single object may emit a
bunch of different messages, and you want to handle some of them.  If
an EventEmitter encounters an error, it emits an 'error' event, which
throws if it is unhandled.

var ee = new EventEmitter
ee.on('someEvent', function (data) {
  // some event happened, and wants to tell me about data
})
ee.on('error', function (er) {
  ohnoes(er)
})

EventEmitters are highly optimized, and very cheap to create and use.
(They need to be, because node internally creates bazillions of them.)

You can easily have a class that extends EventEmitter to add
additional semantics:

function Foo() {}
util.inherits(Foo, EventEmitter)
Foo.protoype.getPrimes = function (n) {
  if (this._gettingPrimes) {
    this.emit('error', new Error('already getting some!'))
  }
  this._gettingPrimes = true
  // go and get some primes.
  // when you have one:
  this.emit('prime', thePrime)
  // maybe when you're done:
  this._gettingPrimes = false
  this.emit('end')
})


3. Streams

Streams : Time :: Array : Space

A Stream is a special EventEmitter subclass designed for dealing with
data flowing into or out of some underlying interface, such as a file
or socket.  It's used throughout Node, though a bit clumsily in
places, and the interface and usage is scheduled to be cleaned up in
v0.9.

Readable streams have a .pipe() method that can be used to send the
bytes coming *out* of the readable stream *into* the writable stream.



For this prime generator thing, presumably each prime number takes
some relevant amount of time to generate, but it doesn't sound much
like a Stream, per se.  I'd subclass EventEmitter, and just define
semantics for your events that makes sense for your specific use case.

On Sat, Apr 28, 2012 at 09:29, Tim Caswell <t...@creationix.com> wrote:
>
>
> On Sat, Apr 28, 2012 at 10:25 AM, Oliver Leics <oliver.le...@gmail.com>
> wrote:
>>
>> On Sat, Apr 28, 2012 at 4:07 PM, Tim Caswell <t...@creationix.com> wrote:
>> > Stream: A stream is closer to a callback than an event emitter even
>> > though
>> > [..]
>> > 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.
>>
>> Is the following statement always true?
>>
>> "A prime number generator that implements the stream-interface but
>> never pipes its data to another process or socket should better not
>> implement the stream-interface."
>>
>> (I don't want to troll or something like that, I really want to know
>> your opinions about that)
>
>
> In that case I would say that a stream interface is overkill.  But like most
> things, it depends on what you're interfacing with and your personal
> preference for abstraction.  If the code you're interfacing with expects a
> stream interface, even though it's in-process, there is something to be said
> for a consistent interface.
>
> A prime number generator is a "generator".  That means you pull data from it
> when you want the data.  There is no outside force creating the numbers
> pushing them to you.  The generator Bruno wrote would be a good abstraction
> for an on-demand prime generator. (Or use harmony generators if you prefer
> it as a language feature)
>
> If the generator uses threads and is generating primes as fast as possible
> in a worker, then maybe an event emitter or stream would make sense.  In
> that case there is a real event source.  Some other code running in another
> thread notifies you when it has data.  If the data is small enough to buffer
> and you don't need the primes till they are all generated, then use a single
> callback.  It's less times to synchronize the two threads.  If there is a
> ton of data and it's infeasible to buffer or wait till it's all done, then
> emit data as it happens (Event Emitter).  If you want to pipe the data to
> some other process or write to disk or something that had hard bandwidth
> constraints, then use a full stream and implement a way to pause the number
> generator when the target is busy.  That way you don't end up generating
> numbers faster than you can write them and blow up in memory.
>
> --
> 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