-
Notifications
You must be signed in to change notification settings - Fork 16
ConstraintJS Internals
ConstraintJS automatically detects and manages dependencies between constraint variables.
For instance, if y
is declared as:
y = x.add(1); // y <- x + 1
Then a dependency from x
to y
is established, which is illustrated conceptually with an arrow from x
to y
:
y depends on x (think of x's value as flowing to y)
This dependency lets ConstraintJS know that whenever `x` changes, `y` should also change. When we call:x.set(9)
y
and any other variables that depend on x
are marked as invalid, which means that their values needs to be recomputed:
y is invalidated after x changes
The .invalidate()
function can be used to manually invalidate a variable (.set()
automatically invalidates its value).
ConstraintJS uses a "pull model" for constraints, meaning that y
is only recomputed when its value is requested; not as soon as it's invalidated. When y
's value is valid, ConstraintJS caches its value so that it isn't recomputed unnecessarily. To illustrate, consider the following snippet of code, where although x
's value changes three times, y
's value is only recomputed twice:
var y = cjs.constraint(function() {
console.log("recomputing y");
return x.get() + 1; // y <- x + 1
});
x.get(); // = 2
y.get(); // = 3, "recomputing y" printed
y.get(); // = 3, nothing printed
x.set(9); // x <- 9
x.set(10); // x <- 10
x.set(11); // x <- 11
y.get(); // = 12, "recomputing y" printed
For the curious, this academic paper contains more in-depth details on ConstraintJS's inner mechanics.