如何 cache/reuse apollo-server 解析器响应

How to cache/reuse apollo-server resolver response

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

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

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(); 两次。有没有办法避免两次调用它们?喜欢 "caching" 如果它来自同一个请求?

同一类型字段的解析器将并行执行,因此 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 })
  })
}

或者,您可以 return 事务 class 的实例,并以这种方式缓存 getTo()getFrom() 的值:

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

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