1

我想把节点放在枪集中。

const Gun = require('gun');
const _ = require('lodash');
require( "gun/lib/path" );

const gun = new Gun({peers:['http://localhost:8080/gun']});

const watchers = [ 
  {
    _id: '123',
    _type: 'skeleton',
    _source: {
      trigger: {
        schedule: {
          later: 'every 1 sec'
        }   
      }   
    }   
  },  
  {
    _id: '456',
    _type: 'snowman',
    _source: {
      trigger: {
        schedule: {
          later: 'every 1 sec'
        }   
      }   
    }   
  }
]; 

const tasks = gun.get('tasks'); 

_.forEach(watchers, function (watcher) {
  let task = gun.get(`watcher/${watcher._id}`).put(watcher);
  tasks.set(task);
});

最后,我只收到以下消息。脚本卡在终端中。

Only a node can be linked! Not "undefined"!

侦听器端没有任何内容:

const tasks = gun.get('tasks');
tasks.map().val(function (task) {
  console.log('task', task);
});

怎么了?


仅当我将对象更改为更简单的对象时,才会在侦听器端收到结果watchers,例如:

_.forEach(watchers, function (watcher) {
  let task = gun.get(`watcher/${watcher._id}`).put({id: '123'});
  tasks.set(task);
});

结果:

task { _: { '#': 'watcher/123', '>': { id: 1506953120419 } },
  id: '123' }
task { _: { '#': 'watcher/456', '>': { id: 1506953120437 } },
  id: '123' }
4

1 回答 1

1

@trex 您正确地将其报告为错误,我们在此处修复了此问题:https ://github.com/amark/gun/issues/427 。

当一个节点被引用时,它不应该表现得好像它是undefined. 这是一个错误。

但是,将来,有些人可能会尝试链接非节点引用。因此,我想回答您主题的标题(但请注意,您的实际问题已得到修复,您的代码现在应该在 v0.8.8+ 中正常工作)。

为什么我会得到“只能链接一个节点!” 错误?

假设您提到了枪中的东西:

var thing = gun.get('alice').get('age');

您可能希望将其添加到集合(也称为表、列表或集合)中,如下所示:

gun.get('list').set(thing);

你会得到一个“只有一个节点可以链接!” 错误。这很烦人!但原因如下:

因为age(或任何其他示例数据)是原始值,将其添加到表中会导致其丢失上下文。相反,我们可以使用以下方法获得完全相同的最终结果:

var person = gun.get('alice').get('age');
gun.get('list').set(thing);
gun.get('list').map().get('age').on(callback);

现在我们返回一个年龄列表,但这些年龄将始终反映他们最新/当前的实时上下文。如果我们只是将年龄添加到表中,它将不再具有实时上下文。

这就是为什么只能链接节点的原因,因为您尝试链接的该节点上的任何数据都可以通过遍历该节点来链接。在这种情况下,它是通过.get('age')在列表之后执行的。这有几件非常酷的事情:

  1. 节省了带宽。GUN 只会age从列表中的每个项目加载属性,它不会加载项目的其余部分。它会同步您询问的数据。
  2. 一切都是可遍历的。无论您的数据在图表中的什么位置,无论是文档、键/值对、表格、关系数据还是其他任何东西,都可以从图表中的节点开始遍历。这是可能的,因为它始终是链接的节点,而不是原始数据。

注意:令人沮丧的是,您可能事先不知道某个枪支引用是节点还是原语,因为您总是可以允许您的用户动态更改该引用上的数据。这将要求您优雅地处理错误,并尽您所能猜测用户的意图。您可以通过对应用程序中的数据实施架构来避免此问题。如果您的应用已部署,我们强烈建议您使用架构。

但是,如果我想要链接原始数据,而不是实时上下文怎么办?

那么你所要做的就是传递数据的实际值,而不是对它的引用。像这样:

gun.get('list').set(thing);

与往常一样,聊天室非常友好,所以来打个招呼吧。请使用 StackOverflow 提问,但请在聊天室中通知我们。聊天室用于快速帮助,SO 用于解决其他人将从中受益的长期问题。

感谢您提出这个问题!我希望这回答了它,如果您有任何进一步的问题或疑虑,请给我们留言。

于 2017-10-16T11:33:53.010 回答