【问题标题】:How to cache/reuse apollo-server resolver response如何缓存/重用 apollo-server 解析器响应
【发布时间】:2018-04-19 03:18:11
【问题描述】:

我想知道是否有办法在我的解析器中避免不必要的调用。

我的解析器如下所示:(最小化)

Transaction: {
  bkFrom(transaction) {
    return transaction.getFrom(); //<-- CACHE THIS?
  },
  bkTo(transaction) {
    return transaction.getTo(); //<-- CACHE THIS?
  },
  type(transaction) {
    return new Promise(async function(resolve, reject) {
      const [From, To] = await Promise.all([
        transaction.getFrom(), //<-- CACHE THIS? If bkFrom() is already triggered
        transaction.getTo(),  //<-- CACHE THIS? If is bkTo() already triggered
      ]);
      switch (true) {
        case From.isKonto && To.isKonto:
          resolve(TransactionType.INTERN);
        case !From.isKonto && To.isKonto:
          resolve(TransactionType.INCOMING);
        case From.isKonto && !To.isKonto:
          resolve(TransactionType.OUTGOING);
        default:
          resolve(null);
      }
    });
  },
},

如果我这样查询:

getTansactions(limit: 10) {
    type
    bkFrom {
      id
      name
      isKonto
    }
    bkTo {
      id
      name
      isKonto
    }
  }

它将调用transaction.getFrom();transaction.getTo(); 两次。有没有办法避免两次调用它们?如果它来自同一个请求,就像“缓存”一样?

【问题讨论】:

    标签: apollo apollo-server


    【解决方案1】:

    相同类型字段的解析器将并行执行,因此type 的解析器无法知道bkFrom 的解析器解析到什么。我认为处理此问题的最佳方法是将逻辑上移一级,进入getTansactions 的解析器。

    getTransactions: async () {
      // Get the transactions first
      const transactions = await someCallToGetTransactions()
      // Grab all our additional calls and use Promise.all to call them concurrently
      const promises = transactions.reduce((memo, t) => {
        memo.push(t.getTo())
        memo.push(t.getFrom())
        return memo
      }, [])
      const toFrom = await Promise.all(promises)
      // Merge the results into one array
      return transactions.map((t, index) => {
        const bkTo = toFrom[index * 2]
        const bkFrom = toFrom[(index * 2) + 1]
        const type = getType(bkTo, bkFrom) //calculate type from your other fields
        return Object.assign({}, t, { bkTo, bkFrom, type })
      })
    }
    

    或者,您可以返回 Transaction 类的实例,并以这种方式缓存 getTo()getFrom() 的值:

    class Transaction {
      async getTo () {
        if (!this._to) {
          this._to = await //whatever
        }
        return this._to
      }
    }
    

    这样,第一次调用getTo() 时,它会获取该值并将其保存在内存中。对它的任何后续调用(对于同一实例)只会从内存中返回值。

    【讨论】:

    • 这会触发 getTo() 和 getFrom() 即使 typebkFrom/bkTo 没有被请求,对吧?
    • 是的,这就是这种方法的缺点。请参阅编辑以获取其他想法。
    猜你喜欢
    • 2019-02-03
    • 2020-01-28
    • 2019-10-18
    • 2020-02-26
    • 2021-07-29
    • 2018-10-04
    • 2018-08-30
    • 2019-03-26
    • 1970-01-01
    相关资源
    最近更新 更多