0

I was trying to simulate(in Browser) async iterable on a ReadableStream using this below code:

class DBSource{
    constructor(){
        this.data=[1,2,3,4,5,6];
    }
    pull=(controller)=>{
        //simulates a slow DB connection
        return new Promise((res)=>{
            setTimeout(()=>{
                let c = this.data.shift();
                if(c){
                    controller.enqueue(c);
                }else{
                    controller.close();
                }
                res();
            },1000);
        })
    }
}

let stream = new ReadableStream(new DBSource());
function streamAsyncIterator(stream,preventCancel) {
    const reader= stream.getReader();
    return {
        next:()=>{
            return reader.read();
        },
        return:(value)=>{
            if(preventCancel){
                reader.releaseLock();
            }else{
                reader.cancel();
            }
            return {};
        },
        throw:(exception)=>{
            if(preventCancel){
                reader.releaseLock();
            }else{
                return reader.cancel(exception);
            }
            return exception;
        },
        [Symbol.asyncIterator]:()=>{
            return this;
        }
    };
};
(async()=>{
    try{
        console.log("Started: ... ");
        for await(const a of streamAsyncIterator(stream, false)){
            console.log(a);
        }
        console.log("Loop over");
    }catch(e){
        console.log(e);
    }
})();

This code gives me error in firefox (and almost similar in chrome):

TypeError: (intermediate value).next is not a function
    <anonymous> debugger eval code:53
    <anonymous> debugger eval code:60

I have to simulate it as chrome seems to not support async iteration over a readable stream yet. The code seems perfectly fine to me, but yet gives me error. What could possily wrong and how to make it work? In specifically I wanted to simulate this kind of code : Async Iteration of ReadableStream.

for await (const chunk of stream.values({ preventCancel: true })) {
  // Do something with 'chunk'
  break;
}
Anurag Vohra
  • 1,781
  • 12
  • 28
  • Your iterator looks pretty synchronous. [See MDN's example for an example using async generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator#try_it) – Heretic Monkey Mar 10 '23 at 15:45
  • Your problem is `[Symbol.asyncIterator]:()=>{ return this; }`, which returns not the iterator object but whatever `this` value the `streamAsyncIterator()` function was called on. Do not unnecessarily use arrow function! Just use method definition syntax for methods. – Bergi Mar 10 '23 at 16:40

0 Answers0