You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A key feature of watch is that the sources and callback function are handled separately. As such, when watch is called, it is not required to run the provided callback. The immediate option allows to configure the eager behavior of the callback when the watcher is first set up; if set to true, immediate causes the callback to be (eagerly) executed upon calling watch.
An API to pause and resume watchers was recently introduced. If a paused watcher's sources change, the watcher's callback will be executed once the watcher is resumed. This is partly required to properly keep track of dependencies. However, the ability to configure the callback's behavior is lost. As mentioned before, an advantage of watch is that sources and callback are independent. Thus, it should be possible to configure whether the callback itself gets executed when a watcher is resumed.
Currently, it could be said that a watcher's callback executes eagerly on resume; if its laziness could be configured, the pause and resume methods could be used to have more precise control over when may a watcher callback be executed. In particular, pause and resume could be used to fully prevent the execution of the callback while the watcher is paused. Without the lazy behavior, the callback may or may not execute on resume. With lazy behavior, resuming becomes more similar to first setting up a watcher; it indicates that, from that point on, the callback should be executed when a dependency updates.
Prior Art
The target functionality could be achieved with the public API only. See, for example, the two following projects' solutions:
I think that the most conservative way to support this feature is through a new watch option. Here, I'll use lazyResume. The target API is shown below:
constsrc=ref(0)const{ pause, resume }=watch(src,cb,{lazyResume: true})pause()// Pause watchersrc.value++// Does not run `cb`resume()// Runs internal effect to properly track dependencies, but doesn't run `cb`
Detailed design
In principle, only two files in the reactivity package (from 3.6 minor branch) could be refactored to implement this feature:
First, a watcher must be able to identify that its scheduler function was called from its effect's resume method. For this, the ReactiveEffect.resume method could be refactored as depicted below.
The scheduler method can be directly called instead of notify since the latter, when called from resume, is guaranteed to simply call scheduler.
A new SCHEDULED_ON_RESUME flag is introduced for custom scheduler methods to detect whether they were invoked from resume. An scheduler boolean parameter could be used instead, but more type adjustments would be required since ReactiveEffect.scheduler's signature would change.
Secondly, inside watch.ts, on the watch function implementation, the watcher's effect.scheduler method should be defined in the following way when a callback is provided (i.e., when using the watch(src, cb) signature).
The scheduledOnResume variable will be used to inform the job whether it was first scheduled by the resume method. In addition, when resume is called and lazyResume is true, scheduler might need to clear the effect's DIRTY flag so that further sync source updates are able to re-run the scheduler. Alternatively, a new ReactiveEffect flag might be set to ensure a subsequent sync dependency update notifies the watcher's effect.
Finally, a simple check can be performed inside the watcher's job to determine if the callback should be run. The scheduledOnResume variable should also be reset.
constjob=(immediateFirstRun)=>{//...if(cb){constnewValue=effect.run()// effect is always run to properly track dependenciesif(lazyResume&&scheduledOnResume){oldValue=newValue}elseif(/*...*/){// Execute callback}scheduledOnResume=undefined// Reset variable}//...}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Feature Description
A key feature of
watch
is that the sources and callback function are handled separately. As such, whenwatch
is called, it is not required to run the provided callback. Theimmediate
option allows to configure the eager behavior of the callback when the watcher is first set up; if set totrue
,immediate
causes the callback to be (eagerly) executed upon callingwatch
.An API to pause and resume watchers was recently introduced. If a paused watcher's sources change, the watcher's callback will be executed once the watcher is resumed. This is partly required to properly keep track of dependencies. However, the ability to configure the callback's behavior is lost. As mentioned before, an advantage of
watch
is that sources and callback are independent. Thus, it should be possible to configure whether the callback itself gets executed when a watcher is resumed.Currently, it could be said that a watcher's callback executes eagerly on resume; if its laziness could be configured, the pause and resume methods could be used to have more precise control over when may a watcher callback be executed. In particular, pause and resume could be used to fully prevent the execution of the callback while the watcher is paused. Without the lazy behavior, the callback may or may not execute on resume. With lazy behavior, resuming becomes more similar to first setting up a watcher; it indicates that, from that point on, the callback should be executed when a dependency updates.
Prior Art
The target functionality could be achieved with the public API only. See, for example, the two following projects' solutions:
watchIgnorable
watchControlled
There's a blog article showing a particular use case for this feature.
Motivation
These alternatives, however, introduce overhead; for non-sync watchers, two watchers are required. See their implementations:
Target API
I think that the most conservative way to support this feature is through a new
watch
option. Here, I'll uselazyResume
. The target API is shown below:Detailed design
In principle, only two files in the
reactivity
package (from 3.6 minor branch) could be refactored to implement this feature:First, a watcher must be able to identify that its
scheduler
function was called from itseffect
'sresume
method. For this, theReactiveEffect.resume
method could be refactored as depicted below.scheduler
method can be directly called instead ofnotify
since the latter, when called fromresume
, is guaranteed to simply callscheduler
.SCHEDULED_ON_RESUME
flag is introduced for customscheduler
methods to detect whether they were invoked fromresume
. Anscheduler
boolean parameter could be used instead, but more type adjustments would be required sinceReactiveEffect.scheduler
's signature would change.Secondly, inside
watch.ts
, on thewatch
function implementation, the watcher'seffect.scheduler
method should be defined in the following way when a callback is provided (i.e., when using thewatch(src, cb)
signature).The
scheduledOnResume
variable will be used to inform the job whether it was first scheduled by theresume
method. In addition, whenresume
is called andlazyResume
istrue
,scheduler
might need to clear theeffect
'sDIRTY
flag so that further sync source updates are able to re-run the scheduler. Alternatively, a newReactiveEffect
flag might be set to ensure a subsequent sync dependency update notifies the watcher's effect.Finally, a simple check can be performed inside the watcher's job to determine if the callback should be run. The
scheduledOnResume
variable should also be reset.Beta Was this translation helpful? Give feedback.
All reactions