async function *Greeting({name}) {
yield <div>Hello {name}</div>;
for await ({name} of this) {
yield <div>Hello again, {name}</div>;
}
}
Currently, in the above example the rendered output will always be Hello again, {name} because the initial yield resumes and the for await loop is immediately started. This feels surprising, because it means you can鈥檛 do setup stuff in the async generator component outside the loop. We should make the context async iterator unavailable if the component yields before opening it.
Hi! I've found this issue after struggling for a bit after upgrading crank.
Is it possible to force the async generator to refresh in that situation?
I will refactor my component to work without that.
Calling this.refresh() just before for await doesn't work.
@KrysKruk If you鈥檙e yielding before the for await, it will suspend before the for await starting in 0.3.0. I apologize if this is a breaking change! You can both yield and have the for await resume immediately by scheduling a refresh:
/** @jsx createElement */
import { createElement, Fragment } from "@bikeshaving/crank";
import { renderer } from "@bikeshaving/crank/dom";
async function *Greeting({name}) {
this.schedule(() => this.refresh());
yield <div>Hello {name}</div>;
for await ({name} of this) {
yield <div>Hello again, {name}</div>;
}
}
renderer.render(<Greeting name="Brian" />, document.body);
If you have a code example I鈥檓 happy to help debug!
I鈥檓 not sure why calling this.refresh doesn鈥檛 work from directly within the async generator component execution. There might be a reason I prevented it. I may have to investigate this.
Thanks for so fast answer! 馃挭
No need to apologize. Breaking changes are expected at this stage.
this.schedule(() => this.refresh()) is a nice solution. Thank you!
I still need to change the way I'm thinking (I mostly work with React) and async generators can be challenging - that's mostly why I was struggling with this.
Thanks again for the help!
@KrysKruk Feel free to ask questions about async generators or anything whenever. Always happy to help!
I still need to change the way I'm thinking (I mostly work with React) and async generators can be challenging - that's mostly why I was struggling with this.
No I think this was mostly my fault. I made this.refresh fail silently when it鈥檚 called synchronously while a generator component is executing. This is because if you don鈥檛 do this, generator components may throw Generator is already executing errors. While you should never call this.refresh from within the main body of a sync generator component, with async generator components I鈥檓 not so sure we need this same restriction or if async generator components throw errors if you iterate them twice synchronously.
I need to investigate this, and I also need to start logging errors from this.refresh calls which happen when the component is unmounted and or currently executing.