Я закончил тем, что использовал что-то вроде предложенного Дразиллом, но это стало немного грязным. Я полагаю, что это облажалось бы, если бы вы звонили дважды, не дожидаясь окончания первого раза, из-за того, как работают события.
var save_multiple_stores = function(stores, success, fail) {
if (stores.length === 0) {
if (success) {
success();
}
} else {
var store = stores.pop();
var listeners = {}
var unbind_listeners = function() {
for (var evt in listeners) {
store.un(evt, listeners[evt]);
}
}
var onsuccess = function() {
unbind_listeners();
save_multiple_stores(stores, success, fail);
}
var onfail = function() {
unbind_listeners();
if (fail) {
fail();
}
}
store.on('save', onsuccess);
listeners.save = onsuccess;
store.on('exception', onfail);
listeners.exception = onfail;
var num_records = store.save();
//save event will not fire if there are no changed records
if (num_records <= 0) {
onsuccess();
}
}
};