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