[✨] support qwik functions(use*) after async callsites(await...)
#175
Replies: 8 comments
-
|
You shouldnt be putting async code directly in a component function. |
Beta Was this translation helpful? Give feedback.
-
|
@DustinJSilk that sure is an alternative solution, but it still is more verbose |
Beta Was this translation helpful? Give feedback.
-
|
BTW accessing signal( |
Beta Was this translation helpful? Give feedback.
-
|
Hi @revintec ! This is not a simple change According to @manucorporat , adding |
Beta Was this translation helpful? Give feedback.
-
right! that's why we dont allow it. this is not a good idea, all this processing should be done inside a useTask! |
Beta Was this translation helpful? Give feedback.
-
|
thanks for the history, I didn't know that below is an example with only one use case that allows async: component$(async()=>{
const somedata=await(await fetch(...)).json()
return <>{JSON.stringify(somedata)}</>
})if not, we have to add more boilerplate code, it's like callback hell all over again: interface UselessDefinition{dataRef:Signal<...>}
const UselessComponentToIsolateReendering=component$<UselessDefinition>(({dataRef})=>{
return<>{dataRef.value?JSON.stringify(dataRef.value):"loading maybe? but this text won't show up anyways"}</>
})
component$(()=>{
const uselessIntermediateVariable=useSignal<...>()
fetch(...).then((uselessName)=>{
uselessName.json().then((uselessName2)=>{
uselessIntermediateVariable.value=uselessName2
}).catch(...)
}).catch(...)
if(!uselessIntermediateVariable.value)return; // this line triggers a error, but it works at runtime
return<UselessComponentToIsolateReendering dataRef={uselessIntermediateVariable}/>
})maybe a little exacerbated because of the long variable/type name, but you get the point if we assume |
Beta Was this translation helpful? Give feedback.
-
|
about the execution context, I understand why they got messed up, and it seems we can restore them like this component$(({restoreExecutionContext})=>{
...
await ...
restoreExecutionContext()
...
qwikFunctionCall...
return ...
})but I think that's not very user-friendly, so until a better idea come along, let's leave that to another PR :) I've edited the original post according to this |
Beta Was this translation helpful? Give feedback.
-
|
We moved this issue to |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
in version
0.18.1, latest version as of writing, we can't use qwik functions(use*) afterawaitthis limitation is here to because when qwik functions are called, a proper
executionContextmust be recoverablebut it's an implementation detail and it makes qwik harder to use, requires more boilerplate code(
useSignal<...>(...),useTask$(async...),if(!signal.value)return, etc.) when async callsites are involvedI propose a way to solve this, in 2 steps
const restoreEnv=useCallsite()orconst restoreEnv=useAsync()byfunction useCallsite(){const ctxt=tryGetInvokeContext();return()=>void(_context=ctxt);}I actually appended
export const USE_CONTEXT=()=>{const ctxt=_context;return()=>_context=ctxt}tocore.mjsfor testing, and currently found no major problems. there're however some edge cases and warningsthen users can use it like this:
awaitcallsites, and addrestoreEnv(...)automaticallybut this is tricky so we can implement
1first, which should be easier to implement and reason aboutoriginal POST follows
Is your feature request related to a problem?
currently code like
export default component$(async()=>...)would compile and work finenotice the
asyncthere. but vscode is reporting syntax errorDescribe the solution you'd like
can we modify
https://github.com/BuilderIO/qwik/blob/70880b71995361202ae0b4725454cb2bd008ab2d/packages/qwik/src/core/component/component.public.tsto update thecomponent$signature?from
export type OnRenderFn<PROPS> = (props: PROPS) => JSXNode<any> | nullto
export type OnRenderFn<PROPS> = (props: PROPS) => ValueOrPromise<JSXNode<any> | null>it's a small change but I don't know if it's acceptable/compatible/safe
Describe alternatives you've considered
export default component$(()=><>{(async()=>...)()}</>)but that's ugly and verbose
Additional context
No response
Beta Was this translation helpful? Give feedback.
All reactions