2013-07-04 10 views
31

Używam meteor 0.6.4.Meteor.methods zwraca undefined

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

Zwraca niezdefiniowany ilekroć wykonać

Meteor.call('random', 10); 

Jakieś pomysły jak mogę ominąć ten?

Odpowiedz

57

Jest to zupełnie normalne zachowanie: metoda serwer wywołuje w Meteor są documented być asynchroniczny:

Na kliencie, jeśli nie przechodzą wywołania zwrotnego, a nie jesteś wewnątrz odgałęzienie, rozmowa powróci nieokreślony, a nie będziesz w stanie uzyskać wartości zwracanej przez metodę.

Oznacza to, że gdy poprosisz o Meteor.call sposobu wykonania zdalnie na serwerze, połączenie lokalne metoda nie jest blokowanie i zwraca undefined natychmiast. Gdy metoda została wywołana na serwerze to wyśle ​​wynik asynchronicznie do klienta, więc należy je odzyskać przy użyciu wzorca callback:

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

Anonimowa funkcja zwrotna zostanie wywołana na kliencie jak najszybciej wynik metody serwera jest wysyłany z powrotem do klienta.

Jest jeszcze jedna subtelna cecha Meteor unieważniająca to, o czym właśnie mówiłem: kompensacja opóźnienia i kody metod. W przypadku, gdy wywołanie metody serwera może zostać poprawnie skonfigurowane w kliencie i wykonane w ten sposób natychmiast, bez konieczności ponownego odwiedzania serwera, można zdefiniować, co nazywa się stubiem (lub symulacją) metody.

Powszechnym przykładem użycia tego zachowania jest natychmiastowe wstawienie do lokalnej bazy danych (podzbioru replikacji po stronie klienta) jakiejś opublikowanej treści użytkownika (np. Komentarz pod artykułem na blogu): dostępne są wszystkie niezbędne dane i logika, a także ma sens symulowanie wstawiania po stronie serwera. To, co dzieje się dalej, to to, że użytkownik widzi aktualizację strony zaraz po przesłaniu treści, nawet jeśli serwer nie potwierdził jeszcze tych zmian. (jest to przykład zastosowania kompensacji opóźnienia w Meteor).

Oczywiście, że serwer ma ostatnie słowa na temat tego, co ostatecznie zostanie wstawione do bazy danych, oznacza to, że gdy zostanie uruchomiona metoda podwójna po stronie serwera, jej działania będą miały pierwszeństwo i zastąpią to, co zostało wstawione do lokalnej bazy danych.

Aby zdefiniować taki skrót metody, należy po prostu zdefiniować tę samą nazwę metody serwera na kodzie klienta. Jeśli deklaracja metoda jest zdefiniowana w kodzie udostępnionym (wysłane zarówno do klienta i serwera), można sprawdzić, czy wywołanie metody jest rzeczywiście symulacja sprawdzając właściwość isSimulation:

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

UPDATE 26/11/2014: @ steph643 skomentował, jak ostatnia część mojej poprzedniej odpowiedzi była w rzeczywistości błędna, tutaj jest korekta.

Należy pamiętać, że wywołania metody serwera można zawsze wywoływać za pomocą składni synchronicznej, ponieważ środowisko serwera zapewnia odpowiedni mechanizm blokowania (włókna).

Na kliencie jeśli jednak coś powrót z metody zalążek, może być wykonywany synchronicznie tylko jeśli jesteś wewnątrz innego odgałęzienie można pobrać wynik w sposób synchroniczny, czyli

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

Takie zachowanie jest nieco dziwne, biorąc pod uwagę, że operacje pobierania Mongo (wstawianie/aktualizowanie/usuwanie) są implementowane jako metody Meteor, a ich wersje klienckie implementują poprawne kody pośredniczące (modyfikację podzbioru lokalnej bazy danych minimongo), które mogą być wykonywane synchronicznie.

+0

Dzięki, musiałem się z tym pogodzić, ale to bardzo pomogło. http://www.eventedmind.com/posts/meteor-methods – jaggy

+2

"Jeśli zwrócisz coś z kodu pośredniego metody, możesz go wykonać synchronicznie na kliencie i możesz pobrać wynik w zwykły sposób". To nie jest prawda. Wywołanie metody wydane przez klienta zwraca 'niezdefiniowany', czy istnieje skrót, czy nie. Cf. doc: "Na kliencie, jeśli nie przekazujesz wywołania zwrotnego i nie znajdujesz się wewnątrz kodu pośredniczącego [co oznacza, że ​​nie wywołujesz metody z innego kodu pośredniczącego], wywołanie zwróci się niezdefiniowane i nie będziesz w stanie uzyskać zwracana wartość metody ". Obowiązuje to niezależnie od tego, czy do metody dołączono kod pośredniczący. – steph643

+0

Dzięki za wskazanie tego, podążam też za twoim tematem dotyczącym rdzenia meteorytów. Zacytowałem dokumenty w mojej odpowiedzi i wyraźnie stwierdzają, że synchroniczne wykonywanie skrótów metod po stronie klienta może odbywać się tylko w ramach innego wywołania metody, ale miało to niewielki sens, więc założyłem, że jest inaczej. – saimeunt