2013-07-04 11 views
31

Sto usando Meteor 0.6.4.Meteor.methods restituisce un valore non definito

Meteor.methods({ 
    random: function(top){ 
    var random = Math.floor((Math.random()*(top+1))); 
    return random; 
    } 
}); 

restituisce il valore undefined ogni volta che eseguo

Meteor.call('random', 10); 

Tutte le idee come posso superare questo?

risposta

57

Questo è un comportamento perfettamente normale: metodo server chiama in Meteor sono documented essere asincrona:

Sul client, se non si passa una richiamata e non sei all'interno di uno stub, chiamata tornerà indefinito, e non avrai modo di ottenere il valore di ritorno del metodo.

Ciò significa che quando si chiede un metodo Meteor.call di eseguire in remoto sul server, la chiamata al metodo locale è non bloccante e restituisce undefined immediatamente. Quando il metodo è stato chiamato sul server invierà il risultato in modo asincrono al cliente, così si dovrebbe recuperare utilizzando il modello di callback:

Meteor.call("myMethod", arguments..., function(error, result){ 
    if(error){ 
    console.log(error.reason); 
    return; 
    } 
    // do something with result 
}); 

La funzione di callback anonima sarà chiamata sul client non appena il risultato del metodo server viene rinviato al client.

C'è un'altra funzione sottile in Meteor che annulla ciò che ho appena detto: compensazione della latenza e stub dei metodi. Nel caso in cui la chiamata al metodo server può essere simulato correttamente nel client e quindi giustiziato subito senza un andata e ritorno al server, è possibile definire quello che viene chiamato uno stub (o la simulazione).

Un caso di utilizzo comune per questo comportamento è l'inserimento immediato nel database locale (subset di replica lato client) di alcuni contenuti utente appena pubblicati (un commento sotto un articolo del blog per esempio): tutti i dati e la logica necessari sono disponibili e senso di simulare insertion lato server. Cosa succede dopo è che l'utente vede la pagina web aggiornata non appena ha presentato il suo contenuto anche se il server non ha ancora confermato questi cambiamenti. (Questo è un esempio di come la latenza di compensazione è implementato in Meteor).

Naturalmente il server ha parole finali in ultima analisi, ciò che viene inserito nel database, questo significa che quando viene eseguito il metodo doppia lato server, le sue azioni avranno la precedenza e sostituire ciò che è stato inserito nel database locale.

Per definire tale stub, non resta che definire lo stesso nome del server metodo su codice client. Se la dichiarazione del metodo è definita in codice condiviso (spediti sia per client e server), è possibile verificare se la chiamata al metodo è in realtà una simulazione verificando la proprietà isSimulation:

Meteor.methods({ 
    myMethod: function(arguments...){ 
     if(this.isSimulation){ 
      // called from the client 
     } 
    } 
}); 

AGGIORNAMENTO 26/11/2014: @ steph643 commentato come l'ultima parte della mia risposta precedente era effettivamente sbagliato, ecco un correzione.

Si noti che sul metodo server le chiamate possono sempre essere richiamate utilizzando la sintassi sincrona in quanto l'ambiente server fornisce un meccanismo di blocco adeguato (fibre).

Sul client tuttavia, se si torna qualcosa da uno stub, che può essere eseguito in modo sincrono solo se sei all'interno di un altro stub e si può recuperare il risultato in maniera sincrona, cioè

Meteor.methods({ 
    intermediateMethod: function(){ 
    return " WORLD"; 
    }, 
    method: function(){ 
    var result = "HELLO"; 
    result += intermediateResult; 
    var intermediateResult = Meteor.call("intermediateMethod"); 
    return result; 
    } 
}); 

Questo comportamento è un po 'strano considerando che le operazioni di raccolta di Mongo (insert/update/delete) sono implementate come metodi Meteor e le loro versioni client stanno implementando stub validi (modifica del sottoinsieme di database locale minimongo replicato) che possono essere eseguiti in modo sincrono.

+0

Grazie, dovevano ottenere la mia testa intorno ad esso, ma questo ha aiutato molto. http://www.eventedmind.com/posts/meteor-methods – jaggy

+2

"Se restituisci qualcosa da un metodo stub, può essere eseguito in modo sincrono sul client e puoi recuperare il risultato nel solito modo". Questo non è vero. Una chiamata al metodo emessa dal client restituisce "indefinito" se esiste o meno uno stub. Cf. il doc: "Sul client, se non si passa una richiamata e non si è all'interno di uno stub [che significa che non si chiama il metodo dall'interno di un altro stub], la chiamata verrà restituita indefinita, e non si avrà modo di ottenere il valore di ritorno del metodo ". Questo si applica indipendentemente dal fatto che uno stub sia collegato o meno al metodo. – steph643

+0

Grazie per la precisazione, sto seguendo il vostro argomento su meteora-core troppo. Ho citato i documenti nella mia risposta e affermano esplicitamente che l'esecuzione sincrona lato client degli stub del metodo può avvenire solo all'interno di un'altra chiamata di metodo, ma non ha molto senso, quindi ho assunto il contrario. – saimeunt

Problemi correlati