2014-07-23 12 views
12

Sto tentando di memorizzare nella cache il risultato di una chiamata Ajax utilizzando la funzione da Underscore.js. Non sono sicuro della mia implementazione. Inoltre, come recuperare i dati dei risultati memorizzati nella cache utilizzando la chiave. Qui di seguito è la mia realizzazione:utilizzando la funzione memoize con underscore.js

codice Javascript:

var cdata = $http 
.get(HOST_URL + "/v1/report/states") 
.success(function(data) { 
    //put the result in the angularJs scope object. 
    $scope.states = data; 
}); 

//store the result in the cache. 
var cachedResult = _.memoize(
    function() { 
     return cdata; 
    }, "states"); 

È il mio utilizzo di Memoize per memorizzare il risultato di AJAX è corretta. Inoltre, una volta inserito nella cache, come recuperare in base alla chiave. io "afferma".

risposta

30

Cerchiamo di capire come funziona _.memoize, ci vuole una funzione che deve essere memoized come primo argomento e memorizza nella cache il risultato del ritorno funzione per il dato parametro. La prossima volta, se la funzione memoized viene richiamata con lo stesso argomento, utilizzerà il risultato memorizzato nella cache e il tempo di esecuzione della funzione può essere evitato. Quindi è molto importante ridurre il tempo di calcolo.

Come accennato, la funzione fibonaci di cui sopra memoized funziona perfettamente bene come l'argomento ha un tipo primitivo.

Il problema si verifica quando è necessario memoizzare una funzione che accetta un oggetto. Per risolvere questo, _.memoize accetta un argomento facoltativo hashFunction che verrà utilizzato per cancellare l'input. In questo modo puoi identificare in modo univoco i tuoi oggetti con le tue funzioni hash.

L'implementazione predefinita di _.memoize (utilizzando la funzione di hash predefinita) restituisce il primo argomento così com'è: nel caso di JavaScript restituirà [Object object].

Quindi per es.

var fn = function (obj){ some computation here..} 
var memoizedFn = _.memoize(fn); 

memoizedFn({"id":"1"}) // we will get result, and result is cahced now 

memoizedFn({"id":"2"}) // we will get cached result which is wrong 

perché l'impostazione predefinita ha la funzione in _.Memoize è la funzione (x) {return x}

il problema può essere evitato facendo passare una funzione di hash

_.memoize(fn, function(input){return JSON.stringify(input)}); 

Questo è stato un vero e proprio aiuto per me quando ero utilizzando _.memoize per una funzione che era lavorando sugli argomenti degli array.

Spero che questo aiuti molte persone nel loro lavoro.

+0

Risolti alcuni errori di grammatica e aggiunte alcune informazioni aggiuntive. –

5

_.memoize prende una funzione:

var fibonacci = _.memoize(function(n) { 
    return n < 2 ? n: fibonacci(n - 1) + fibonacci(n - 2); 
}); 

Si dovrebbe capire che questo è solo un funzione wrapper in più che fa la funzione che si passa come argomento più intelligente (Aggiunge oggetto di mapping in più per esso).

Nell'esempio sopra la funzione che calcola il numero di Fibonacci viene avvolta con _.memoize. Quindi su ogni chiamata di funzione (fibonacci(5) o fibonacci(55555)) l'argomento passato corrisponde al valore restituito, quindi se è necessario chiamare un'altra volta fibonacci(55555), non è necessario calcolarlo nuovamente. Recupera solo quel valore da quell'oggetto di mappatura che è fornito da _.memoize internamente.

-1

Se si utilizza il numero $http di Angular.js, è probabile che si desideri passare semplicemente {cache : true} come secondo parametro al metodo get.

Per memorizzare valori utilizzando coppie di valori chiave, è possibile utilizzare $cacheFactory come descritto in altre risposte come here. In sostanza:

var cache = $cacheFactory('cacheId'); 
cache.put('states', 'value'); 
cache.get('states'); 
Problemi correlati