rvagg / through2

Tiny wrapper around Node streams2 Transform to avoid explicit subclassing noise
MIT License
1.9k stars 106 forks source link

How can I resume()/pause() a through2 stream? <-- Error: Cannot switch to old mode now. #35

Closed bitliner closed 9 years ago

bitliner commented 9 years ago

I have a through2 stream whose function runs

...
self.pause();
somethingAsyncOnChunk(chunk);
done();
...

and the stream is resumed when an event happens (outside the callback passed to through2.obj constructor).

But this code throws Error: Cannot switch to old mode now..

I am using pause()/resume() because I cannot pass any callback to the function somethingAsyncOnChunk(chunk)

Apparently it is not possible to use them because the stream I have is in a pipeline (pipe()). But how may I pause()/resume() the stream?

mafintosh commented 9 years ago

Could you add a full example? In general you shouldn't use pause/resume - just wait to call done() until you are ready to accept the next chunk

bitliner commented 9 years ago

The problem is that if I call done() then the stream reads the next chunks, and I have to avoid it for synchronization related problems. I have to let it read next chunk only when an external event happens.

I was trying to call done() outside of the function of the stream (after having assigned the function done() to an outer variable ), but this throws an exception as well. This exception is Error: no writecb in Transform class

The point is: how can I pause/resume() the stream? Is it possible?

The code calling done outside of the stream's function is:

var next;

var stream = through2.obj(function(chunk, encoding, done) {
        next = done;

        sometingAsyncWithoutCallback(chunk);
        //done();

    });

mymod.onEvent(function(){
  next()
})
mafintosh commented 9 years ago

.resume/.pause throttles the readable end. what you are talking about is throttling the writable end. the way to that in streams3 is using the cork() method as I understand it. this isn't supported in through2 yet.

I would still implement this by waiting to call done

var stream = through(function(data, enc, cb) {
  stream.push(data)
  stream.next = function() {
    stream.next = function() {}
    cb()
  }
})

stream.write('hello')
stream.write('world')
...
stream.next()
bitliner commented 9 years ago

That works. Thanks