I am little bit confused by behavior explanation of deferred calculation defined on koputed variable.
Such puted variable might be defined with property deferEvaluation: true which should postpone evaluation to the moment when any other property ask for variable value (see .html),
When regular koputed variable is extended by extend({deferred: true}) it calls calculation asynchronously and postpone it until all currently running "threads" finishes (see .html).
These two settings sound very similar, but each do something pletely different.
Can anybody confirm to me that I am right or explain the difference if I am mistaken?
I am little bit confused by behavior explanation of deferred calculation defined on ko.puted variable.
Such puted variable might be defined with property deferEvaluation: true which should postpone evaluation to the moment when any other property ask for variable value (see http://knockoutjs./documentation/puted-reference.html),
When regular ko.puted variable is extended by extend({deferred: true}) it calls calculation asynchronously and postpone it until all currently running "threads" finishes (see http://knockoutjs./documentation/deferred-updates.html).
These two settings sound very similar, but each do something pletely different.
Can anybody confirm to me that I am right or explain the difference if I am mistaken?
Share Improve this question asked Jan 31, 2017 at 14:16 Jan StanicekJan Stanicek 1,2911 gold badge17 silver badges31 bronze badges2 Answers
Reset to default 6deferEvaluation
is only about deferring initial evaluation. Normally when you create a puted, its evaluator is called right then, synchronously, which means (amongst other things) that all of the observables it depends on must already be initialized. Using deferEvaluation
prevents that, and makes the first call to the puted's evalutor function happen the first time anything subscribes to the puted (or never, if nothing ever does). After that, it has no further effect; the puted is still re-evaluated every time anything it depends on changes, immediately.
.extend({deferred: true})
is about always deferring execution of the evaluator until after the task that created or changed it pletes (and then typically before the next UI update). It's not just about the initial evaluation, it means every time the observables the puted depends on change, those changes are allowed to settle by making the puted's evaluation asynchronous (after the current task) and waiting for them to stabilize.
Here's a snippet showing using neither of them, using deferEvaluation
and using .extend({deferred: true})
. Note the differences in when the evaluators are called.
setTimeout(function() {
console.log("---- Using neither:");
var ob1 = ko.observable(10);
console.log("creating c1");
var c1 = ko.puted(function() {
console.log("c1 evaluated");
return ob1() * 2;
});
console.log("Setting ob1 to 20");
ob1(20);
console.log("subscribing to c1");
c1.subscribe(function(newValue) {
console.log("c1's new value is " + newValue);
});
console.log("Setting ob1 to 30");
ob1(30);
console.log("Setting ob1 to 40");
ob1(40);
}, 50);
setTimeout(function() {
console.log("---- Using .extend({deferEvaluation: true}):");
var ob2 = ko.observable(10);
console.log("creating c2");
var c2 = ko.puted(function() {
console.log("c2 evaluated");
return ob2() * 2;
}, null, { deferEvaluation: true });
console.log("Setting ob2 to 20");
ob2(20);
console.log("subscribing to c2");
c2.subscribe(function(newValue) {
console.log("c2's new value is " + newValue);
});
console.log("Setting ob2 to 30");
ob2(30);
console.log("Setting ob2 to 40");
ob2(40);
}, 200);
setTimeout(function() {
console.log("---- Using .extend({deferred: true}):");
var ob3 = ko.observable(10);
console.log("creating c3");
var c3 = ko.puted(function() {
console.log("c3 evaluated");
return ob3() * 2;
}).extend({ deferred: true });
console.log("Setting ob3 to 20");
ob3(20);
console.log("subscribing to c3");
c3.subscribe(function(newValue) {
console.log("c3's new value is " + newValue);
});
console.log("Setting ob3 to 30");
ob3(30);
console.log("Setting ob3 to 40");
ob3(40);
}, 400);
.as-console-wrapper {
max-height: 100% !important;
}
<script src="https://cdnjs.cloudflare./ajax/libs/knockout/3.4.0/knockout-min.js"></script>
deferEvaluation
will prevent the puted from determining its initial value (and dependencies) until something actually accesses it. That could be programmatic (accessing the puted in code) or via a binding. It can be useful for "chicken and egg" scenarios where the puted's code needs to wait for other things to be setup before running or for efficiency if the puted will be triggered several times in initialization before its value is needed/read. The pureComputed
functionality can acplish the same thing with additional benefits over the life of the puted (http://knockoutjs./documentation/puted-pure.html).
extend({deferred: true})
will opt the observable/observableArray/puted into the deferred updates functionality. Deferred updates means that you can synchronously make multiple updates to an observable/observableArray or to the dependencies of a puted and it will only trigger a single change (which happens asynchronously). This can have be very beneficial to a plex UI, as you will avoid multiple re-renders for intermediate changes.
If I was starting a new application, I would turn on deferred updates (ko.options.deferUpdates = true
) and use ko.pureComputed
as much as possible for the best performance and memory usage.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744757903a4591991.html
评论列表(0条)