Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript async generator, for socket

I am trying to understand TS async generators.

In Node.js, I open a socket, read all data from it, then close it.

I am attempting to make this into an async generator over the chunks of data.

async function* connectAndRead() {
    const socket = net.connect(80, 'localhost');
    socket.on('data', data => ???);
    socket.on('end', socket.close());
}

It is possible to make an async generator for data read from a socket?

like image 317
Paul Draper Avatar asked Jul 04 '26 23:07

Paul Draper


1 Answers

It's possible, something like this should work until Node.js streams implement the async iteration protocol themselves:

import net from "net";

async function* socketIterator(
    host: string, port: number, initialSend?: Buffer | string,
): AsyncIterableIterator<Buffer> {
    let ended: boolean = false;
    let error: Error | undefined;
    let wake: () => void;

    const socket = net.connect(port, host)
        .on("readable", () => { wake(); })
        .on("end", () => { ended = true; wake(); })
        .on("error", (err) => { error = err; wake(); });

    if (initialSend) {
        socket.write(initialSend);
    }

    try {
        for (;;) {
            // wait for next event on socket
            await new Promise<void>((res) => wake = res);
            // yield all data available on socket
            for (let chunk = socket.read(); chunk; chunk = socket.read()) {
                yield chunk;
            }
            if (error) { throw error; }
            if (ended) { break; }
        }
    }
    finally {
        socket.end();
    }
}

async function main(): Promise<void> {
    const iter = socketIterator("httpbin.org", 80, "GET / HTTP/1.0\r\n\r\n");
    for await (const chunk of iter) {
        console.log(chunk.toString());
    }
}

main().catch(console.error);
like image 165
Mika Fischer Avatar answered Jul 07 '26 13:07

Mika Fischer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!