Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How does watch function work? #77

Open
tangjurine opened this issue Jul 20, 2023 · 2 comments
Open

How does watch function work? #77

tangjurine opened this issue Jul 20, 2023 · 2 comments

Comments

@tangjurine
Copy link

tangjurine commented Jul 20, 2023

From the docs:

However, the watcher also detects when a dependency is no longer being used by a function and turns $off tracking for those properties.

In our example, this means that when logTotal is false it will not call our total() function again until data.logTotal is set back to true.

The example function in the doc was:

function total () {
  if (data.logTotal) {
    console.log(`Total: ${data.price * data.quantity}`);
  }
}

But what if the function was:

function total () {
  if (data.logTotal == ifMathTheoremIsTrue()) {
    console.log(`Total: ${data.price * data.quantity}`);
  }
}

Isn't knowing when a dependency is used by an arbitrary function reducible to the Halting Problem?

So when can the watcher detect changes, and when can it not?

@justin-schroeder
Copy link
Owner

justin-schroeder commented Jul 20, 2023

Good question. However, the halting problem need not apply since we actually run the code — there is no static analysis or deterministic algorithm. Conceptually this is not that complicated (it is also, by the way, how signals work and how vue works — it is a clever trick though), in your example:

function total () {
  if (data.logTotal == ifMathTheoremIsTrue()) {
    console.log(`Total: ${data.price * data.quantity}`);
  }
}

we start by running the function and observing which properties are touched. Given a state of:

data = {
  logTotal: 1,
  price: 1,
  quantity: 10
}

And given that ifMathTheoremIsTrue() has no dependencies on data and returns 1, then the dependencies of the first run are:

data.logTotal, data.price, data.quantity

The only time we need to re-run this function are if any of those dependencies are changed. Lets say logTotal now changes to 1. We re-run the function and the dependencies are:

data.logTotal

we can now diff the dependency results:

| data.logTotal, data.price, data.quantity
|---------------------------------------
| data.logTotal
|---------------------------------------
call $off on data.price, data.quantity

Hope that helps clear up how this works 👍

@Clonkex
Copy link

Clonkex commented Oct 12, 2023

Ah, that's very helpful! I also had this question. When I first read the documentation it seemed like magic, but now I see it just tracks the dependencies from each run. If logTotal changes to false, the function will run again and now it will know that price and quantity are no longer relevant. If logTotal changes back to true, it will know to start tracking price and quantity again. Very clever indeed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants