1

收听更新

var node = gun.get('watcher/f0de26c0-a29f-11e7-8661-154b982951a4')
node.get('stats').on(function (v, k) {
console.log('v:', v);
console.log('k:', k);
});

更新

node.put({
  stats: {
    num: 3
  },
  name: 'trex'
});

如果您node多次使用同一个对象更新 ,则每次在侦听器端都有更新。

{"_":{"#":"j94c5jht6u6KTIoltGt7mHx",">":{"num":1508935385873.435}},"num":3}

{"_":{"#":"j94c5jht6u6KTIoltGt7mHx",">":{"num":1508935385873.435}},"num":3}

{"_":{"#":"j94c5jht6u6KTIoltGt7mHx",">":{"num":1508935386550.19}},"num":3}

仅当属性值更改时如何接收更新?

 var gun = new Gun();
 var result = document.getElementById('result');
 
 var node = gun.get('watcher/f0de26c0-a29f-11e7-8661-154b982951a4');
 node.get('stats').on(function (v, k) {
   displayValue(v);
   console.log('v:', v); 
   console.log('k:', k);
 });

 
function displayValue (v) {
  var p = document.createElement("p");
  var t = document.createTextNode(JSON.stringify(v));
  p.appendChild(t);
  result.appendChild(p);
};
 
function createNode () {
  node.put({
    stats: {
      num: 3
    },
    name: 'trex'
  }); 
}

function updateNode() {
  node.put({
    stats: {
      num: 3
    },
    name: 'trex'
  });
}

function deleteNode() {
  while (result.firstChild) {
    result.removeChild(result.firstChild);
  }
}

var createNodeBtn = document.getElementById('create_node');
createNodeBtn.onclick = createNode;
var updateNodeBtn = document.getElementById('update_node');
updateNodeBtn.onclick = updateNode;
var deleteNodeBtn = document.getElementById('delete_node');
deleteNodeBtn.onclick = deleteNode;
<script src="https://rawgit.com/amark/gun/master/gun.js"></script>
<button type="button" id="create_node">create</button>
<button type="button" id="update_node">update</button>
<button type="button" id="delete_node">clean</button>

<div id=result></div>

4

1 回答 1

1

@特雷克斯,

这里有两件事:

  1. 当没有可观察到的变化时停止更新。
  2. 没有变化时停止更新。

这是两个非常不同的东西。让我们看看他们。

没有可观察到的变化时停止更新

第 2 次更新,即使是相同的数据,仍被视为新更新。这是一个重要的例子:

  1. 爱丽丝保存foo1.
  2. Bob 保存foo2.
  3. Alice在听到 Bob 的更新之前保存foo为AGAIN(因为延迟)。1

那么 Alice 将丢弃 Bob 的更新,因为 Alice在最近的时间再次保存了相同的数据。因此,虽然这看起来不像对 Alice 的更改,但这是所有对等方都需要处理的合法更改。

因为上述内容很重要,gun 默认情况下不会对此进行重复数据删除。您必须自己使用一些简单的逻辑对其进行重复数据删除:

var was;

gun.get('some').get('data').on(function(data, key){
    if(was === (was = data)){ return }
    cb(data, key);
});

注意:JS 原语可以是===,但如果data是对象(gun 中的节点),那么您需要添加一些额外的逻辑来进行深度比较,可能使用 lodash 或 underscore 之类的实用程序库。

额外开销的逻辑实际上是 gun 默认不执行此操作的另一个原因,因为并非所有应用程序都需要此行为。对于需要这种行为的应用程序(比如你的),使用这个扩展很容易定制你的枪

Gun.chain.uniqueUpdates = function(cb){
    var was;

    return this.on(function(data, key){
        /* your deduplication/deep-comparison logic here */
        cb(data, key);
    });
}

现在你可以用你的新模块替换你应用中的 using on 了!

gun.get('some').get('data').uniqueUpdates(cb);

没有变化时停止更新

您可以轻松应用上述技术(停止可观察到的变化),它还将阻止枪支使用重复数据射击。

为什么在没有变化的情况下会用重复的数据开枪?

GUN 实际上在图的根部对更新进行了重复数据删除,但不幸的是,链接 API 目前 (v0.8.9) 不进行重复数据删除。这意味着如果您要从外部发送枪支“旧”数据,它将对其进行重复数据删除。然而,链式 API 的内部机制异常复杂,当我们尝试在那里添加重复数据删除时,它导致的错误比事件发射器上重复消息的不便(已经设计为处理多个消息)带来的不便更多。

也就是说,我们计划在 GUN 稳定并准备好生产后解决这个问题,因为这对我和新开发人员来说是一个持续的麻烦。从技术上讲,这不是错误的行为,但它是不必要的/令人讨厌的,因此目前的优先级为 0。

于 2017-10-30T16:58:29.003 回答