-
Notifications
You must be signed in to change notification settings - Fork 13
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
Allow side-effectful call expressions without observation or caching #724
Comments
This behavior is different for "magic" attributes and "magic" between-tags as shown here: https://codepen.io/justinbmeyer/pen/wvvBGEo?editors=1111 This is due to the catching @rjgotten mentioned. This asymmetry isn't great. |
Yeah, this is confusing. To summarize:
|
@phillipskevin yeah, attributes cache the compute. This helped the performance of the "spinner" example as we wouldn't need to rebuild computes (and all the scope walking) for something like:
I don't remember why this wasn't also done for "magic between-tags". Maybe for a reason similar to this. An alternate approach would be to
This would allow people to opt out with var compute = new Observation( ObservationRecorder.ignore( ()=> {
return Math.random()*obs.value
}) ) |
That would actually still break if you have something side-effectful that also observes, right? 😞 However, after having given this some more thought over the course of the day, maybe something altogether different would work to solve the general problem. I'll explain. Currently there's a So... What if a conceptual In such a case, all the parts that need to be observable can be inside the outer helper. And the parts that are side-effectful can be inside the returned function. Quick draft for the import { stache } from "can";
const uuid = 0;
function uuid( prefix = "", options ) {
if ( stache.isOptionsLike( prefix ) {
[ prefix, options = [ "", prefix ];
}
options.metadata.late = true;
return () => prefix + (++uuid);
}
uuid.requiresOptionsArgument = true;
export { uuid as default }; Here the observable (and bound/cached) part is in the outer function which is made observable and whose result is cached in the evaluator cache. This observable then returns a function which is uncached and unobserved and facilitates the side-effectful sequence number. The general logic flow would still remain: pull the observable from the evaluator cache; call |
Proposal
Extend call expressions to pass in
notWrappedInObservation
flag from individual user-supplied helpers, allowing non-observed functions to return non-cached values.Benefits
Allows users to author side-effectful helpers. One use-case is a helper that implements unique IDs as sequence-numbers; increasing with each call. E.g.
This currently doesn't work, as call expressions are always wrapped in observations which cache their result value; and the observations are in turn put into the expression evaluator cache. I.e. both
uuid
calls above will return the same result.Strip away the observation; turning it into a plain function, and things do work.
Drawbacks
None that I am aware of. The code to add this isn't even that many lines to adapt.
Migration
This can be implemented strictly as a feature toggle that requires opt-in on individual helper functions. This means it wouldn't break anything.
Implementation details
Call.prototype.value
has a small piece of code that would need to be adjusted:can-stache/expressions/call.js
Lines 117 to 123 in 942724f
This would become:
The text was updated successfully, but these errors were encountered: