Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to wrap a setInterval in an async generator function?

Tags:

javascript

Without using the Streams API, is it possible to wrap a setInterval in an async generator function, to simulate a never-ending stream?

I know how to do it using setTimeout to supply the delay.

Using setTimeout:

const wait = (delay = 500) => new Promise((resolve) => setTimeout(resolve, delay))

async function * countUp(count = 0) {           
    while(1) (await wait(), yield count++)           
}

(async ()=> {
    for await(let el of countUp())
        console.log(el)
})()
like image 331
Ben Aston Avatar asked Sep 13 '25 02:09

Ben Aston


1 Answers

No. Or: not easily. Async generator functions are promise based, and promises don't deal well with repetitive callbacks. Also setInterval does not support any form of backpressure.

Of course you can implement the streams API yourself, which comes down to making a queue of promises. You can take the code from that answer and write

function countUp(count = 0) {
    const q = new AsyncBlockingQueue()
    setInterval(() => {
        q.enqueue(count++)
    }, 500)
    return q // has a Symbol.asyncIterator method
}

(async() => {
    for await (const el of countUp())
        console.log(el)
})()
like image 94
Bergi Avatar answered Sep 15 '25 18:09

Bergi