Recursive sync watcher stops tracking computed #12033
Labels
❗ p4-important
Priority 4: this fixes bugs that violate documented behavior, or significantly improves perf.
regression
scope: reactivity
Vue version
3.5.6
Link to minimal reproduction
https://play.vuejs.org/#eNp9Uctqw0AM/BWxlzjgOC19QXBCH4TSHtrS9rhQ3I2cOFnvmn04KcH/Xq2N0xxKbtLMSMxIe3ZXVUntkU1YaoUpKgcWna9mXBVlpY2DPRjMY9hmTqxiELqsvMMFNJAbXcKAZgdccSW0sg4MTIM8Ohv2iCCkH4qiIUxnYJI6kx5JwlW7NhIxRHXL7bkCKHJqYQbnw66HfmQ0Cm3DVROTr1x6u5rAwP4oMYCG9qXjLgO5p8ZhWcnMIXUAe8oBTQOjUIlQpd/eOa3gVshCbKacBfM3nM0edTruOJpMx0drWMycpVx5sUzWViu6WmuQsxCxkGheK1dQbs4mvXXOMin19rnFnPEY97hYodj8g6/tLmCcvRm0aGrk7MC5zCzRdfT84wV3VB/IUi+8JPUJ8h2tlj547GT3Xi3I9pGudfvU/r5Qy0873zlUtg8VjLY/aPWc0fsfTkT/s3uRXPa/oyt+1WjCTjrgRXKVXLPmFzJo0y8=
Steps to reproduce
Just click the button.
What is expected?
The rendered values should be
1
.What is actually happening?
The rendered values are
6
.System Info
No response
Any additional comments?
This changed in 3.5.6. In 3.5.5 and earlier it renders
1
, as expected.I found this while investigating #11956. I still don't know what causes the memory leak, but after staring at #11944 for a bit I noticed the potential problem I've reported here.
This is what I believe is happening...
When a
computed
is notified, theNOTIFIED
flag gets set for bothComputedRefImpl
and itsdep
. These are queued in a batch. WhenendBatch()
is called it handles thedep
first, clearing theNOTIFIED
flag from thedep
and then callingtrigger()
. But theNOTIFIED
flag is still set for theComputedRefImpl
, so it can't be notified whiletrigger()
is running.I used
watch
withflush: 'sync'
in the reproduction, as that was the most direct way to take advantage of the mismatched flags. I'm not sure whether there's a more 'normal' way to hit this timing issue.The text was updated successfully, but these errors were encountered: