2012-11-02 15 views
8

Jak zdobyć klienta method.call, aby poczekać na zakończenie funkcji asynchronicznej? Obecnie osiąga koniec funkcji i zwraca undefined.Kod asynchroniczny MeteorJS w synchronicznej metodzie Meteor.methods

Client.js

Meteor.call('openSession', sid, function(err, res) { 
    // Return undefined undefined 
    console.log(err, res); 
}); 

Server.js

Meteor.methods({ 
    openSession: function(session_id) { 
     util.post('OpenSession', {session: session_id, reset: false }, function(err, res){ 
      // return value here with callback? 
      session_key = res; 
     }); 
    } 
}); 
+0

Myślę, że nie jest możliwe wykonywanie zadań asynchronicznych wewnątrz metod meteorytowych od klienta. Na serwerze za pomocą Fibre może być opcja. – Andreas

Odpowiedz

6

Najnowsze wersje Meteor dostarczyły nieudokumentowane Meteor._wrapAsync funkcję, która włącza funkcję ze standardowym (err, res) zwrotnego do funkcji synchronicznej, co oznacza, że ​​bieżący Fibre ulega zwrotowi aż do powrotu zwrotnego, a następnie używa Meteor.bindEnviro w celu zachowania aktualnych zmiennych środowiskowych Meteor (takich jak Meteor.userId()).

Proste użycie byłoby jak:

asyncFunc = function(arg1, arg2, callback) { 
    // callback has the form function (err, res) {} 

}; 

Meteor.methods({ 
    "callFunc": function() { 
    syncFunc = Meteor._wrapAsync(asyncFunc); 

    res = syncFunc("foo", "bar"); // Errors will be thrown  
    } 
}); 

Można również użyć function#bind, aby upewnić się, że asyncFunc nazywa się z właściwym kontekście przed owijając go. Aby uzyskać więcej informacji, zobacz: https://www.eventedmind.com/tracks/feed-archive/meteor-meteor-wrapasync

6

udało mi się znaleźć odpowiedź w this gist. Aby uruchomić kod asynchroniczny z metody method.call, należy użyć Futures, które wymuszają oczekiwanie na funkcję.

var fut = new Future(); 
    asyncfunc(data, function(err, res){ 
     fut.ret(res); 
    }); 
    return fut.wait(); 
+0

Chciałbym zasugerować przyszłość/obietnicę, ale nie zdawałem sobie sprawy, że jest wbudowany w Meteor. Przydatne wszędzie. – Dror

+1

Jesteś prosty G. To jest kod poziomu dzwoniącego, tutaj – OneChillDude

+1

Futures nie jest już częścią rdzenia Meteor, więc to już nie działa. – iiz

0

Aktualizacja: Przepraszam, powinienem był przeczytać to pytanie ostrożniej. Wygląda na to, że to pytanie również zostało zadane i odpowiedziało here.

Oprócz kontraktów terminowych kolejną wzorzec do rozważenia może być aktualizacja innego modelu za pomocą danych zwróconych przez wywołanie asynchroniczne, a następnie subskrypcja zmian tego modelu.


Z meteor.call documentation wygląda na to argument wynik (err, res) swojej funkcji zwrotnej powinna zawierać wyjście swojej funkcji openSession. Ale nie zwracasz żadnych wartości z funkcji openSession, więc zwracana wartość jest niezdefiniowana.

Można to sprawdzić:

Klient:

Meteor.call('foo', function(err, res) { 
    console.log(res); // undefined 
}); 

Meteor.call('bar', function(err, res) { 
    console.log(res); // 'bar' 
}); 

Serwer:

Meteor.methods({ 
    foo: function() { 
    var foo = 'foo'; 
    }, 
    bar: function() { 
    var bar = 'bar'; 
    return bar; 
    } 
});