watchers for async functions #791
Replies: 2 comments
-
That's a can of worms. First notice that const dep = ref(0);
// dep is a dependency of this effect
watchEffect(() => {
return fsync();
});
function fsync() {
return ref.value;
}
// dep is NOT a dependency of this effect, even though it's read inside fasync()
watchEffectAsync(resume => {
const result = await fasync();
resume();
return result;
});
async function fasync() {
await somePromise();
return ref.value;
} The work-around would be to propagate Then there are specs details to flesh out:
|
Beta Was this translation helpful? Give feedback.
-
@jods4 Sure, you have to pass resume() to inner functions which contain a task chain if you want to track dependencies along the whole chain. There is no way around it. I don't see how AsyncContext could help with that. async function effectFunction(resume){
await resume(/* any expression, promise expected */) // resume wraps the expression
// or
return promiseObject.then(resume(/* thenCallback */)) // resume wraps the callback
}
// resume could look like this
async function resume(something){
if(typeof something === "function"){ // expected to be a callback
// start tracking context
something()
// stop tracking
}
else{ // promise, or anything else
// stop tracking
let result = await something
// start tracking
return result
}
}
|
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.
-
Crazy idea, right? Watchers for async functions, the big gap in the current reactive API.
tldr:
watchEffectAsync
provides you theresume
function.resume()
must be manually written after everyawait
so that the dependency tracking system knows that this function is running on the main thread again.But here's the drawback: Any dependency changes will re-run the whole function. We want to re-run only the parts of the function that are affected by the changed dependencies and avoid doing repeated async work (like requests) for max efficiency.
Done. Unfortunately, we have to branch the function manually since the framework can't manipulate the internals of a function and in many cases can't analyze it since js is dynamic. The compiler can automate this in simple cases via static tracking if it sees that
resume
isn't manually used. But generally these functions must be written with watchEffectAsync in mind.Now, when skipping code we need to restore the context for the code below because usually it wants variables defined above. Example:
Additional features: Explicit list of dependencies passed to options to not track, watchAsync() for explicitly whitelisted dependencies.
Beta Was this translation helpful? Give feedback.
All reactions