2017-11-06 2 views
0

Ich frage mich, ob es eine Möglichkeit gibt, unnötige Aufrufe in meinem Resolver zu vermeiden.Wie man die Antwort des Apollo-Server-Resolvers zwischenspeichert/wieder verwendet

Mein Resolvern sieht wie folgt aus: (minimiert)

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); 
     } 
    }); 
    }, 
}, 

Und wenn ich dies wie folgt mit etwas fragen:

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

Es wäre transaction.getFrom(); und transaction.getTo(); zweimal anrufen. Gibt es eine Möglichkeit, diese zweimal zu vermeiden? Wie "Caching" wenn es von der gleichen Anfrage ist?

Antwort

0

Resolver für Felder desselben Typs werden parallel ausgeführt, daher kann der Resolver für type nicht wissen, was der Resolver für bkFrom gelöst hat. Ich denke, der beste Weg, damit umzugehen, ist, diese Logik eine Ebene höher in den Resolver für getTansactions zu bewegen.

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

Alternativ Sie Instanzen einer Transaktionsklasse zurückkehren konnte, und cachen die Werte für getTo() und getFrom() auf diese Weise:

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

diese Weise das erste Mal getTo() genannt wird, wird es die Abruf Wert und behalte es im Gedächtnis. Alle nachfolgenden Aufrufe (für dieselbe Instanz) geben den Wert nur aus dem Speicher zurück.

+0

Dies würde die getTo() und getFrom() auslösen, auch wenn 'type' und' bkFrom'/'bkTo' nicht angefordert wird, oder? – Skaronator

+0

Ja, das ist der Nachteil dieses Ansatzes. Siehe Bearbeiten für eine andere Idee. –

Verwandte Themen