Is "yield" a blocking operation in a cell

I’ve seen this technique in multiple notebooks:

  while (true) { 
    doSomeSVG(g);
    yield svg.node();
  }

There is clearly a “runner” of the generator calling “next” so maybe it is using a settimeout, or rAF?

I am converting my notebook to a JS version to have both worlds (the Good and the Bad & Ugly!)

My question is: I think tight yield loops are blocking operations in JS. How should I convert to a “runner” that uses async on the next calls? Or maybe I can just use the Observable std lib?

Example: running this on a blank page in the browser works, although too fast to see:

function* nextIntegerGenerator(index) {
  while (true) {
    yield index++
  }
}
nextInteger = nextIntegerGenerator(0)
for (let i = 0; i < 10; i++) {
  document.body.innerText = nextInteger.next().value
}

But this hangs the browser:

while (true) {
  document.body.innerText = nextInteger.next().value
}

Hey Owen.

Not to be too RTFM about this, but I think these are the most helpful place to start with generators + async questions:

If you still have questions — of course we’re happy to help.

RTFM is always good advice and Observable’s docs are great!

The Well Hidden question was basically how to translate to JS. For example:

In short: Observable cells that are generators are consumed by the runtime at 60 frames (60 evaluations) per second.

In raw JS, to run the generator cell at the same speed — you’ll want to set up a requestAnimationFrame() that calls .next() on it at the same speed.

And you can indeed use the standard library in your own programs. There’s really not much in it that is Observable-specific — rather, it’s a collection of JS primitives that are designed to be useful in the context of an Observable notebook, but doesn’t depend on running within one.

2 Likes