You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Doing multiple changes inside transaction() results multiple invocations of observer subscribed via subscribe(). #184
/** * Creates a transaction in which an observable can be set multiple times * but only trigger a computation once. * @param {Function} fn * @return {*} */
...
q.forEach(data=>{if(data._pending!==EMPTY_ARR){constpending=data._pending;data._pending=EMPTY_ARR;data(pending);// This calls all computeds linked to the observable}});
Each observable can only trigger a computation once, so a(1); a(2); a(3) will be ONE call to the subscribe. However, a(1); a(2); a(3); b(1); b(2) will be TWO calls because it's TWO observables and they each get one trigger.
I didn't like this behaviour so in my own reactive library (which is on indefinite hiatus/cancelled 😞) I implemented transaction() to call each observable/signal and gather all of the computeds/wires that would run into a Set() and then call them after only once.
/** * Batch signal writes so only the last write per signal is applied. Values are * committed at the end of the function call. */
...
signals.forEach((signal)=>{// Doesn't run any subscribed wires since `transactionCommit` is setsignal(signal.next);// Does not call computeds.deletesignal.next;signal.wires.forEach((wire)=>transactionWires.add(wire));});transactionCommit=false;_runWires(transactionWires)// Call computeds, once each, in the correct order.
You could make a PR for @luwes and he might accept it. Just collect computeds instead of running them and then batch call them afterwards. This would be a behavioural change tho...might break some apps.
@heyheyhello Thanks for your reply. It seems like a bad idea to make a PR if it's designed to work in this way. And I solved my problem by adding a flag. By the way, Haptic is cool.
Activity
tsugabloom commentedon Oct 28, 2021
Unfortunately this is the programmed behaviour... I know it's not intuitive though. It comes down to this phrasing:
https://github.com/luwes/sinuous/blob/master/packages/sinuous/observable/src/observable.js#L51-L71
Each observable can only trigger a computation once, so
a(1); a(2); a(3)will be ONE call to the subscribe. However,a(1); a(2); a(3); b(1); b(2)will be TWO calls because it's TWO observables and they each get one trigger.I didn't like this behaviour so in my own reactive library (which is on indefinite hiatus/cancelled 😞) I implemented
transaction()to call each observable/signal and gather all of the computeds/wires that would run into aSet()and then call them after only once.https://github.com/heyheyhello/haptic/blob/main/src/state/index.ts#L288-L317
tsugabloom commentedon Oct 28, 2021
You could make a PR for @luwes and he might accept it. Just collect computeds instead of running them and then batch call them afterwards. This would be a behavioural change tho...might break some apps.
caparisen commentedon Oct 29, 2021
@heyheyhello Thanks for your reply. It seems like a bad idea to make a PR if it's designed to work in this way. And I solved my problem by adding a flag. By the way, Haptic is cool.