So you have some large amount of work to be done. Perhaps you prepare some heavy API answer, or parse a large document, or compute vertices for your 3d scene. Something like this:
function computeVertices() {
const vertices = []
for (let i = 0; i < 10_000_000; i++) {
vertices.push(computeVertex(i))
}
return vertices
}
This code works 200ms, the UI looks unresponsive, scrolls are jumping, and transitions are jarred — all the UX is terrible. Is there a nice way to make pauses during this work? Yes! Async generators to the rescue.
That's how it looks:
async function computeVertices() {
const workLimiter = createWorkLimiter()
const vertices = []
for (let i = 0; i < 10_000_000; i++) {
await workLimiter.next()
vertices.push(computeVertex(i))
}
return vertices
}
And here's implementation:
async function* createWorkLimiter(
work = 10,
pause = 6,
) {
let start = Date.now()
for ( ; ; ) {
yield
if (Date.now() >= start + work) {
await delay(pause)
start = Date.now()
}
}
}
function delay(ms) {
return new Promise(resolve =>
setTimeout(resolve, ms)
)
}
Cool, isn't it?
Top comments (0)