I dati nella transazione sono nulli

Ho un problema con le transazioni. I dati nella transazione sono sempre nulli e il gestore di aggiornamento è chiamato solo singe una volta. La documentazione dice:

Per fare ciò, si passa a transaction () una funzione di aggiornamento che viene utilizzata per trasformare il valore corrente in un nuovo valore. Se un altro client scrive nella posizione prima che il nuovo valore venga scritto correttamente, la funzione di aggiornamento verrà richiamata con il nuovo valore corrente e la scrittura verrà ritentata. Ciò si verificherà ripetutamente finché la scrittura non avrà esito positivo senza conflitto o la transazione verrà interrotta non restituendo un valore dalla funzione di aggiornamento

Ora so che non c’è nessun altro cliente che acceda al luogo in questo momento. In secondo luogo, se leggo correttamente la documentazione, la funzione updateCounters dovrebbe essere chiamata più volte nel caso non riesca a recuperare e aggiornare i dati.

L’altra cosa – se tolgo la condizione if (counters === null) l’esecuzione avrà esito negativo poiché i contatori sono null ma in un tentativo successivo la transazione termina correttamente – recupera i dati e fa l’aggiornamento.

semplice once - set su questa posizione funziona bene ma non è sicuro.

Per favore cosa mi manca?

ecco il codice

 self.myRef.child('counters') .transaction(function updateCounters(counters){ if (counters === null) { return; } else { console.log('in transaction counters:', counters); counters.comments = counters.comments + 1; return counters; } }, function(error, committed, ss){ if (error) { console.log('transaction aborted'); // TODO error handling } else if (!committed){ console.log('counters are null - why?'); } else { console.log('counter increased',ss.val()); } }, true); 

ecco i dati nella posizione

 counters:{ comments: 1, alerts: 3, ... } 

Tornando undefined nel tuo blocco if( ... === null ) , stai annullando la transazione. Pertanto, non invia mai un tentativo al server, non si rende mai conto che il valore memorizzato nella cache locale non è lo stesso di quello remoto e non tenta mai con il valore aggiornato (il valore effettivo dal server).

Ciò è confermato dal fatto che committed è false e l’errore è null nella funzione di successo, che si verifica se la transazione viene interrotta.

Le transazioni funzionano come segue:

  • passare il valore memorizzato nella cache locale nella funzione di elaborazione, se non hai mai recuperato questi dati dal server, allora il valore memorizzato localmente è null (il valore remoto più probabile per quel percorso)
  • ottenere il valore di ritorno dalla funzione di elaborazione, se quel valore undefined è undefined interrompere la transazione, altrimenti creare un hash del valore corrente (null) e passarlo e il nuovo valore (restituito dalla funzione di elaborazione) al server
  • se l’hash locale corrisponde all’hash corrente del server, la modifica viene applicata e il server restituisce un risultato positivo
  • se la transazione del server non viene applicata, il server restituisce il nuovo valore, quindi il client richiama di nuovo la funzione di elaborazione con il valore aggiornato dal server fino al completamento corretto
  • quando alla fine ha esito positivo e si verifica un errore irreversibile o la transazione viene interrotta (restituendo undefined dalla funzione di elaborazione), il metodo di successo viene chiamato con i risultati.

Quindi, per fare in modo che funzioni, ovviamente non è ansible interrompere la transazione sul primo valore restituito.

Una soluzione alternativa per ottenere lo stesso risultato – sebbene sia accoppiata e non performante o appropriata come solo usando le transazioni come progettato – sarebbe quella di avvolgere la transazione in una once('value', ...) richiamata, che sarebbe assicurarsi che sia memorizzato nella cache localmente prima di eseguire la transazione.