GraphQL:从兄弟解析器访问另一个解析器/字段输出

时间:2017-01-11 17:30:54

标签: javascript node.js graphql graphql-js

需要一些帮助。我想请求以下数据:

{
  parent {
    obj1    {
        value1
    }
    obj2    {
        value2
    }
  }
}

我需要value1解析器中value2的结果进行计算。

想到在value2中返回一个promise并以某种方式将它带入value1解析器,但是如果value2解析器还没有运行呢?

有什么办法可以做到的?

3 个答案:

答案 0 :(得分:2)

我的直接想法是你可以使用上下文来实现这样的事情。我想象你可以拥有一个像事件发射器一样的缓存来解决竞争条件问题。

例如,假设我们有一些类

class CacheEmitter extends EventEmitter {

  constructor() {
    super();
    this.cache = {};
  }

  get(key) {
    return new Promise((resolve, reject) => {
      // If value2 resolver already ran.
      if (this.cache[key]) {
        return resolve(this.cache[key]);
      }
      // If value2 resolver has not already run.
      this.on(key, (val) => {
        resolve(val);
      });
    })
  }

  put(key, value) {
    this.cache[key] = value;
    this.emit(key, value);
  }
}

然后从你的解析器中你可以做这样的事情。

value1Resolver: (parent, args, context, info) => {
  return context.cacheEmitter.get('value2').then(val2 => {
    doSomethingWithValue2();
  });
}

value2Resolver: (parent, args, context, info) => {
  return doSomethingToFetch().then(val => {
    context.cacheEmitter.put('value2', val);
    return val;
  }
}

我还没有尝试过,但这似乎对我有用!如果你试一试,我很好奇,所以让我知道它是否有效。只是为了记账,你需要确保你实例化“CacheEmitter”#39;类并将其提供给顶层的GraphQL上下文。

希望这会有所帮助:)

答案 1 :(得分:0)

根据graphql-resolvers:“ GraphQL当前不支持某个字段依赖于另一个字段的解析结果”。使用EventEmiter似乎是实现此目标的一种非常过时的方法。 graphql-tools提供了一些辅助功能,使您可以通过多种方式来组成解析器,从而为您提供帮助。

答案 2 :(得分:0)

如果您正在缓存不应该造成任何性能问题的内容,您可以再次在 obj1 解析器中加载 obj2 的 value2。