can.batch.start( batchStopHandler ) and
[can.batch.end can.batch.end( force, callStart )] are used to specify
atomic operations. start
prevents change events from being fired until stop is called.
The following listens to changes on a player:
var player = new can.Map({
tvshow: "The Simpsons"
});
player.bind("change",function(ev, attr, how, newVal, oldVal){
console.log("changed", attr );
});
The "change" callback handler does not get called until
after tvshow is removed, song is added, and stopBatch
is called.
can.batch.start();
player.removeAttr("tvshow");
player.attr("song","What makes you beautiful");
can.batch.stop();
Performance and correctness are the two most common reasons
to use batch operations.
Correctness
Sometimes, an object can be temporarily in an invalid
state. For example, the previous player should have
a tvshow or song property, but not both. Event listeners should
never be called in an intermediate state. We can make this happen
with startBatch, stopBatch and
the can/map/setter plugin as follows:
// Selection constructor function inherits from Observe
Player = can.Map({
// called when setting tvshow
setTvshow: function(newVal, success){
can.batch.start();
this.removeAttr("song")
success(newVal);
can.batch.stop();
},
// called when setting song
setSong: function(newVal, success){
can.batch.start();
this.removeAttr("tvshow")
success(newVal);
can.batch.stop();
}
});
// a new selection instance
var player = new Player({song: "Amish Paradise"});
player.bind("change", function( ev, attr, how, newVal, oldVal ){
console.log("changed", attr, how, player.attr() );
});
console.log("start")
player.attr("tvshow","Breaking Bad");
console.log("end")
Use startBatch and stopBatch to make sure events
are triggered when an observe is in a valid state.
Performance
CanJS synchronously sends events when a property changes.
This makes certain patterns easier. For example, if you
are doing live-binding, and change a property, the DOM is
immediately updated.
Occasionally, you may find yourself changing many properties at once. To
prevent live-binding from performing unnecessary updates,
write the property updates within a startBatch/stopBatch.
Consider a list of items like:
var items = new Items([
{selected: false},
{selected: true},
{selected: false}
])
And a template that renders the number of selected items:
can.batch.start( batchStopHandler )
and [can.batch.endcan.batch.end( force, callStart )
] are used to specify atomic operations.start
prevents change events from being fired untilstop
is called.The following listens to changes on a
player
:The "change" callback handler does not get called until after
tvshow
is removed,song
is added, andstopBatch
is called.Performance and correctness are the two most common reasons to use batch operations.
Correctness
Sometimes, an object can be temporarily in an invalid state. For example, the previous
player
should have atvshow
orsong
property, but not both. Event listeners should never be called in an intermediate state. We can make this happen withstartBatch
,stopBatch
and thecan/map/setter
plugin as follows:Use
startBatch
andstopBatch
to make sure events are triggered when an observe is in a valid state.Performance
CanJS synchronously sends events when a property changes. This makes certain patterns easier. For example, if you are doing live-binding, and change a property, the DOM is immediately updated.
Occasionally, you may find yourself changing many properties at once. To prevent live-binding from performing unnecessary updates, write the property updates within a
startBatch
/stopBatch
.Consider a list of items like:
And a template that renders the number of selected items:
The following updates the DOM once per click:
batchNum
All events created within a
startBatch
/stopBatch
share the same batchNum value. To respond only once for a given batchNum, you can do it like:Automatic Batching
Libraries like Angular and Ember always batch operations. Set this up with:
This batches everything that happens within the same thread of execution and/or within 10 ms of each other.