oh, forgot something about event listeners:

  unlike callbacks, you can decide when you are no longer interested

oh, I just reread the original message where you are talking about
calling the callback multiple times. that is what streams are for. a
callback should never callback twice. those bugs can be really hard to
find.

example, what is wrong with this code:

function parseJson (file, cb) {
  fs.readFile(fileName, function (err, data) {
    if(err) return cb(err);
    try { cb(null, JSON.parse(data)); }
    catch (err) { cb(err); }
  });
}

?

On Sat, Apr 28, 2012 at 11:10 PM, Dominic Tarr <dominic.t...@gmail.com> wrote:
> There is one very good reason for using streams in a case like this,
> that no one has mentioned yet.
>
> First, lets just suppose that N is very large.
> Also lets generate primes in nextTick so that it never blocks for very long.
>
> And the thing that consume's the primes (data) only needs one at a time.
>
> There could be a variety of reasons for this. one might be that it's
> serializing them as a web service.
>
> Now, streams have a cool feature that EventEmitters do not have.
> pause()/resume()
>
> Like streams, TCP also has pause. If the pipe is congested or packets
> are being dropped
> TCP actually slows down a bit.
>
> So if you've made PrimeStream respect pause/resume then it will only
> go as fast as the bottleneck (tcp) can handle them!
>
> you can't do that will callbacks.
>
> a callback might be fine if I only want N < ~500 but what if I want
> billions and billions of primes?
>
> what if I didn't know how many primes I want. I could just say give me
> ALL the primes!
> (N = Infinity) and then close the connection when I'm satisfied.
>
> Another benefit of using streams is that you don't need to keep
> everything in memory.
> you can upload a file that is larger than your ram with streams (I
> think you might need to keep a list of primes to calc the next prime,
> so this benefit doesn't apply to this case)
>
> in summary, use streams if:
>  * you can start using the data before you have received everything.
>  * you would like to be able to throttle the rate something is produced.
>
> usually this is IO related. although, if you have I --> O it may make
> sense to keep the _through_ part in the shape of a stream also.
>
> use callbacks if:
>  * you can't do the next thing until after a thing is done.
>  * you need the whole thing.
>
> example: create a driectory, delete a file. parse a JSON document
> (note, if the document is LARGE and list like, it may make sense to
> stream it)
>
> use an EventEmitter if:
>  * many things will happen
>  * things will happen more than once.
>  * multiple listeners may be interested in an event.
>
> note: createServer(function (req, res) {...
> is not a callback, because callbacks ALWAYS have err as the first argument.
> as pointed out above. it's an event listener. which has no error argument.
>
>
>
> On Sat, Apr 28, 2012 at 10:23 PM, Oliver Leics <oliver.le...@gmail.com> wrote:
>> As i see it: We have a prime number generator that constantly *emits*
>> prime numbers. This is a *stream* of prime numbers. Thus: Use
>> stream.Stream.
>>
>> IMHO implementing this as a stream it is not over-engineered. For me
>> it is the optimum way as streams provides a standard method for
>> everything emitting data. It makes it very easy to hook into that
>> stream of data and do whatever needs to be done with that prime
>> numbers. I do not have to read lots of API documentation. All i need
>> to know: It is a standard node stream of data.
>>
>> BTW: I'm writing this as i recently added 'lazy' to my toolbelt of
>> indispensable node modules.
>>
>> On Sat, Apr 28, 2012 at 12:04 PM, Jorge <jo...@jorgechamorro.com> wrote:
>>> Hi Bruno,
>>>
>>> On Apr 28, 2012, at 11:14 AM, Bruno Jouhier wrote:
>>>
>>>> Neither!
>>>>
>>>> I think that question should be callbacks vs. events vs. streams:
>>>>       • Callback: called only once, when the function is done, to return 
>>>> result (optional) or error.
>>>>       • Event: called repeatedly by the function to notify its listeners. 
>>>> Can be used to send intermediate results as they come.
>>>>       • Stream: higher level concept based on events, with standardized 
>>>> event types (data, end, error, drain) and standardized API (pause, resume, 
>>>> write, ..).
>>>> So, assuming prime computation is asynchronous:
>>>>
>>>>       • If the function computes the N first primes and returns them all 
>>>> at once, it should use a callback.
>>>>       • If the function returns the primes one by one, it should use 
>>>> events. It may also use a stream but that seems a bit over-engineered.
>>>
>>>
>>> Good, yes, that's the way it is in node, but it does not explain *why* it 
>>> is so.
>>>
>>> .readFile() could as well deliver the chunks to the cb as they're read from 
>>> disk, and to use it you'd need to write just one line:
>>>
>>> fs.readFile(path, cb);
>>>
>>> While to do the same with an evented interface there's a lot of boilerplate 
>>> to write, and an extra object to create:
>>>
>>> reader= new fileReaderConstructor(path);
>>> reader.on('data', cb);
>>> reader.on('end', endCB);
>>> reader.on('error', errorCB);
>>>
>>> It seems to me that the former is more functional and makes good use of 
>>> closures (*), while the latter is the approach a classic OOP programmer 
>>> would tend to write instead.
>>>
>>> (*)In JavaScript we don't need to create objects to save state.
>>> --
>>> Jorge.
>>>
>>> --
>>> 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
>>
>>
>>
>> --
>> Oliver Leics @ G+
>> https://plus.google.com/112912441146721682527
>>
>> --
>> 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