How to convert a stream into a generator without leaking resolve from a promise

后端 未结 2 1256
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-06 06:56

I have a stream and I need to convert it to a generator, so an uploader can consume the generic generator.

This means turning:

stream.on(\'data\', ch         


        
2条回答
  •  Happy的楠姐
    2021-01-06 07:32

    You cannot avoid storing the resolve function in a mutable variable if you want to use a single event listener that resolves different promises. You could simplify the promise creation by using the once method similar to the following:

    function streamToIterator(stream) {
        let done = false;
        const end = new Promise(resolve => {
            stream.once('end', resolve);
        }).then(e => {
            done = true;
        });
    
        return {
            [Symbol.iterator]() { return this; }
            next() {
                const promise = new Promise(resolve => {
                    stream.once('data', value => {
                        resolve(value);
                        stream.pause();
                    });
                    stream.resume();
                });
    
                return {
                    value: Promise.race([promise, end]),
                    done,
                };
            }),
        };
    }
    

    Of course, you are doing the racing between end and data yourself, you resume the stream before next is called the first time and most importantly you do the chunking yourself, so this might to be applicable to your situation.

    Apart from that, I'd recommend to check out the buffering internals of node.js streams, it might be easier to read chunks of certain sizes using a lower-level API than data events.

    Also you definitely should have a look at the asynchronous iteration proposal for es-next. The iterable interface you're trying to implement is very similar, and surely they either already have or really would welcome an example of making a node readablestream iterable.

提交回复
热议问题