只能链接一个节点!不是"undefined"!

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

我想把节点放在枪集中。

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' }

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

When a node is referenced, it should not act as if it is undefined. This was a bug.

不过,以后可能会有人尝试linknon-node引用。因此,我想回答您的主题标题(但请注意,您的实际问题已得到解决,您的代码现在应该可以在 v0.8.8+ 中正常工作)。

为什么我会收到 "Only a node can be linked!" 错误?

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

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

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

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

您将收到 "Only a node can be linked!" 错误。这很烦人!但原因如下:

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

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

现在我们得到一个年龄列表,但这些年龄将始终反映他们的 latest/current 实时上下文。如果我们只是将年龄添加到 table,它将不再具有实时上下文。

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

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

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

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

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

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

一如既往,chatroom is super friendly 所以过来打个招呼。请使用 Whosebug 提问,但请在聊天室通知我们。聊天室用于快速帮助,SO 用于解决其他人将从中受益的长期存在的问题。

感谢您提出这个问题!我希望这回答了它,如果您有任何其他问题或疑虑,请告诉我们。