bikeshaving / crank

The Just JavaScript Framework
https://crank.js.org
MIT License
2.7k stars 75 forks source link

Allow generator functions to yield once so we don’t have to use try/finally #239

Closed brainkim closed 1 year ago

brainkim commented 2 years ago

Currently, we use the return() method of generator functions to allow for components to define cleanup code when they’re unmounted. This is nice because it allows us to use try/finally statement, which orders code in the way you would expect, but the extra block and level of indentation is annoying to type out and diff in version control. I wonder if it would be nicer to let the generator resume normally, so that we could allow generators to resume once and break out of the props iterator, so that the try/finally statement is not needed.

Before proposal:

function *Timer() {
  let seconds = 0;
  const interval = setInterval(() => {
    seconds++;
    this.refresh();
  }, 1000);
  try {
    for ({} of this) {
      yield <div>{seconds}s</div>;
    }
  } finally {
    clearInterval(interval);
  }
}

renderer.render(<Timer />, document.body);

After proposal:

function *Timer() {
  let seconds = 0;
  const interval = setInterval(() => {
    seconds++;
    this.refresh();
  }, 1000);
  for ({} of this) {
    yield <div>{seconds}s</div>;
  }

  clearInterval(interval);
}

renderer.render(<Timer />, document.body);

We probably still have to return afterwards anyways to support while (true) type generators, but this would be a nice quality of life change. The way it works for async generators might be a little more complicated.

brainkim commented 1 year ago

Changed in 0.5.0