If a can.batch callback is registered via can.batch.after() while a batch is currently dispatching, the callback is added to the batch's list of callbacks, but is never called after the batch dispatching is complete.
This is most clearly explained with a simple demo of the problem:
var DataModel = can.Map.extend({
define: {
value: {
type: "compute"
}
}
});
var dataModel = new DataModel({
value: 42
});
dataModel.on("value", function() {
can.batch.after(function() {
alert("I'm never called!");
});
});
dataModel.attr("value", 2);
The cause of the problem is in batch.js, in the "stop" method. While processing all the batches, the batch's callbacks are pushed onto a local callbacks array (to gather up ALL callbacks). This is done BEFORE dispatching the batch's events, though. So any callbacks that are registered from within the event handlers are never added to the local list of all callbacks.
var callbacks = [], i;
while (batch = batches.shift()) {
var events = batch.events;
callbacks.push.apply(callbacks, batch.callbacks); // <--- PROBLEM!
dispatchingBatch = batch;
can.batch.batchNum = batch.number;
var len;
if (callStart) {
can.batch.start();
}
for (i = 0, len = events.length; i < len; i++) {
can.dispatch.apply(events[i][0], events[i][1]);
}
can.batch._onDispatchedEvents(batch.number);
// callbacks.push.apply(callbacks, batch.callbacks) <--- SOLUTION!
dispatchingBatch = null;
can.batch.batchNum = undefined;
}
for (i = callbacks.length - 1; i >= 0; i--) {
callbacks[i]();
}
Problem was discovered in canjs v2.3.27
If a can.batch callback is registered via can.batch.after() while a batch is currently dispatching, the callback is added to the batch's list of callbacks, but is never called after the batch dispatching is complete.
This is most clearly explained with a simple demo of the problem:
The cause of the problem is in batch.js, in the "stop" method. While processing all the batches, the batch's callbacks are pushed onto a local callbacks array (to gather up ALL callbacks). This is done BEFORE dispatching the batch's events, though. So any callbacks that are registered from within the event handlers are never added to the local list of all callbacks.