Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow async generator components to use for... of #243

Closed
brainkim opened this issue Nov 19, 2022 · 2 comments
Closed

Allow async generator components to use for... of #243

brainkim opened this issue Nov 19, 2022 · 2 comments
Assignees
Milestone

Comments

@brainkim
Copy link
Member

brainkim commented Nov 19, 2022

There are two disadvantages with the way async generator components are currently designed:

  1. Errors thrown by async generator components don’t have stack traces which point to the the initiators of rendering (usually a call to render() or ctx.refresh()). This is because async generator components resume by unblocking the for await... of loop, rather than via calls to iterator.next().

  2. The differences in behavior between sync generator components and async generator components can be counter-intuitive for newcomers (TODO: find the issue/discussion). And even if you’re familiar with the differences, having to refactor to use for await and switch your mental model so that you can await a promise directly in a stateful component seems like a high cost relative to the benefits.

For instance, one of the big reasons I initially wanted this is that I wanted easy rendering post-conditions, i.e. code which runs after the yield. This is useful but also limited: code after yields only runs after recursive child renders, which isn’t really a useful time to run code, and even if the async generator component does not render asynchronously, the real moment you’re trying to run code is not usually “when the component finishes rendering” but “when the component actually insert rendered children into the active document.”

To be clear, I don’t think async generator components are mis-designed. I still think using for await... of is the best way to implement fallbacks states, and the idea of a component yielding multiple trees per update is elegant. Nevertheless, I do think the cons listed above are important to address.

One of the main themes around the upcoming 0.5 release has been about making things easier to type, and I’ve found a lot of success in inspecting the internal state of components via the props iterators to implement quality of life conveniences. For instance, . This gives me hope that maybe we can allow async generator components to use for... of iterators. The idea would be that if we yield in a for... of loop, we switch to behavior that mimics sync generator components, just async.

This was never impossible: async functions can call sync functions. The one thing I worry about is that now async generator components have three de facto modes: 1. while looping (outside any render loop), 2. for of looping, 3. for await of looping. Is this itself confusing? Not sure.

@brainkim brainkim self-assigned this Nov 19, 2022
@brainkim brainkim added this to the 0.5.0 milestone Nov 19, 2022
@brainkim brainkim changed the title Allow async generator components to use for await... of Allow async generator components to use for... of Nov 19, 2022
@brainkim
Copy link
Member Author

for...of loops in async generator components don’t seem to be throwing correctly, so this is even more important.

brainkim added a commit that referenced this issue Jan 16, 2023
Implements #243

implement after loop logic for for...of loops in async generator components
brainkim added a commit that referenced this issue Feb 1, 2023
Implements #243

implement after loop logic for for...of loops in async generator components
@brainkim
Copy link
Member Author

brainkim commented Feb 1, 2023

Added in 0.5.0

@brainkim brainkim closed this as completed Feb 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant