arqex / freezer

A tree data structure that emits events on updates, even if the modification is triggered by one of the leaves, making it easier to think in a reactive way.
MIT License
1.28k stars 56 forks source link

proper user of transaction #19

Closed aktxyz closed 9 years ago

aktxyz commented 9 years ago

http://jsbin.com/lixota/2/edit?js,console

I have a nested object ...

var json = {
    a: 'aaa',
    b: 'bbb',
    c: {
      d: 'ddd',
      e: 'eee',
      f: {
        h: 'hhh',
        i: 'iii'
      }
    }
};

var freezer = new Freezer( json );
var frozen = freezer.get();

I am using transact() to batch my updates, and have tried the 2 ways shown below ...

// WORKS - transact per node in tree
if (true) {
  var t1 = frozen.transact();
  t1.a = 'aaaaaa';
  t1.b = 'bbbbbb';
  var t2 = frozen.c.transact();
  t2.d = 'dddddd';
  frozen.run();
}

// DOES NOT WORK - single transaction at root node
if (true) {
  var t1 = frozen.transact();
  t1.a = 'aaaaaa';
  t1.b = 'bbbbbb';
  t1.c.d = 'dddddd';
  frozen.run();
}

It looks like I need a transact() per node, wanted to check if this is the way you intended, or if you have any recommendation.

The jsbin at the beginning has a runnable example.

marquex commented 9 years ago

Hi @aktxyz

Thanks for your jsbins, they are really descriptive :)

The transactions are not intended to be the default way of updating a freezer store, but they are really useful if you want to apply a batch of updates to a node. They are also thought to be used with the leaves of the trees, if you use it with nodes that have other nodes inside, the transact method will return an object with frozen nodes inside so, in case that you don't modify them, they are reused at the end of the transaction.

As I said, I wouldn't care about transaction unless I am updating more than 10 elements in an array or something similar.

jwaala commented 9 years ago

I ended up going with something like this...

// DOES WORK
if (true) {
  frozen
    .set('a', 'aaaaaa')
    .set('b', 'bbbbbb')
    .c.set('d', 'dddddd')
}

which seems to be clean and works nicely.

http://jsbin.com/lixota/3/edit?js,console

arqex commented 9 years ago

@jwaala I'm glad you found your way :)

If you use an object as the argument for set you could update a and b at once:

frozen
    .set( {a: 'aaaaaa', b: 'bbbbbb'} )
    .c.set('d', 'dddddd')
;

I can close this now