You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a program that reads itself, by creating a read stream, waiting for it to be readable, and then assigning a data event listener. It prints data on all node versions < 10, but prints nothing on the Node v10.0.0 release.
In situ, cp-file tries to ensure that a stream is readable before creating the destination directory and then calling .pipe to write the file to disk. As far as I can tell, Node v10 changes the behavior of readable streams such that data events are not emitted if you bind the data event listener after readable is emitted.
The provided example is not a good way of using streams, because it will add a new 'data' handler for each emitted chunk (even on Node < 10). In the cp-file it will call resolveevery time there is a new chunk.
The solution (also to the cp-file case) is to use once() instead of on(). See sindresorhus/copy-file#26.
The behavior change introduces in #1899 is semver-major but it seems to work as intended.
That PR is 3 years old and rather long. Moreover the discussion does not contain the words read, readable or stream – Where do I have to look?
I'm not sure what your point is. It is unexpected, if .on('readable') and .once('readable') behave differently, isn't it? (except for the differences mentioned at Handling events only once of course 😉 )
Ok, but both .on('readable', …) and .once('readable', …) create listeners for the 'readable' event, don't they? – I believe, I still don't understand 😕
The difference is that if there is at least one listener for the 'readable' event, on('data', fn) will not resume the stream. once() in the above example makes sure that there are no listeners when on('data', fn) is called.
Activity
lpinca commentedon May 6, 2018
I didn't check but I think behavior changed with #18994.
cc: @nodejs/streams
mcollina commentedon May 6, 2018
The provided example is not a good way of using streams, because it will add a new
'data'handler for each emitted chunk (even on Node < 10). In thecp-fileit will callresolveevery time there is a new chunk.The solution (also to the cp-file case) is to use
once()instead ofon(). See sindresorhus/copy-file#26.I think this can be closed.
schnittstabil commentedon May 6, 2018
That is not a problem, because of the semantics of Promises. You may call
resolveas often as you want, only the first one matters:Please also note, that your suggestion (using
oncefordataevents) does not solve the problem in the example of @tmcw:@mcollina Interestingly, your suggestion to use
.onceinstead of.onforreadableevents seems to solve the issues forcp-fileand the example above:Thus, it seems
.on('readable')and.once('readable')behave differently.lpinca commentedon May 6, 2018
Yes but it's useless overhead.
The suggestion was to use
oncefor'readable', not for'data'.The behavior change introduced in #18994 is semver-major but it seems to work as intended.
schnittstabil commentedon May 6, 2018
That PR is 3 years old and rather long. Moreover the discussion does not contain the words
read,readableorstream– Where do I have to look?I'm not sure what your point is. It is unexpected, if
.on('readable')and.once('readable')behave differently, isn't it? (except for the differences mentioned at Handling events only once of course 😉 )BridgeAR commentedon May 6, 2018
It was a typo when referencing the issue. The "4" was missing at the end. I fixed that by editing the reference.
schnittstabil commentedon May 6, 2018
@BridgeAR Thank you, for clarifying. But, please do not edit my comments in a way, so the discussion does not make sense for readers anymore.
lpinca commentedon May 6, 2018
@schnittstabil my point is that cf5f986 seems to work as expected, specifically:
schnittstabil commentedon May 6, 2018
Ok, but both
.on('readable', …)and.once('readable', …)create listeners for the'readable'event, don't they? – I believe, I still don't understand 😕lpinca commentedon May 6, 2018
The difference is that if there is at least one listener for the
'readable'event,on('data', fn)will not resume the stream.once()in the above example makes sure that there are no listeners whenon('data', fn)is called.