2012-04-20 1 views
2

Я очень удивлен тем, что определения Meteor.method требуют, чтобы результат возвращался, а не вызывался обратный вызов. Но так оно и есть!Как дождаться результатов подпроцесса перед возвратом из Meteor.method

Я пытаюсь создать метод RPC в Meteor, который вызывает методы группы mongoose (это не похоже на то, что данные метеора api позволяют мне делать это, поэтому я работаю над ним). У меня есть что-то вроде этого:

Meteor.methods 
    getdata: -> 
    mongoose = __meteor_bootstrap__.require('mongoose') 
    db = mongoose.connect(__meteor_bootstrap__.mongo_url) 
    ASchema = new mongoose.Schema() 
    ASchema.add({key: String}) 
    AObject = mongoose.model('AObject',ASchema) 
    AObject.collection.group(
     ... 
     ... 
     (err,doc) -> # mongoose callback function 
     # I want to return some variation of 'doc' 
    ) 
    return ??? # I need to return 'doc' here. 

Мой собственный вариант кода размещен выше делает работу ... Я получаю звонки от моего метеора клиента, мангуст все объекты работают их магию. Но я не могу понять, как вернуть результаты в исходный контекст.

Как я могу это сделать?


Ответ Я пошел бы с мой код выглядит следующим образом:

require = __meteor_bootstrap__.require 
Meteor.methods 
    getdata: -> 
    mongoose = require('mongoose') 
    Future = require('fibers/future') 
    db = mongoose.connect(__meteor_bootstrap__.mongo_url) 
    ASchema = new mongoose.Schema() 
    ASchema.add({key: String}) 
    AObject = mongoose.model('AObject',ASchema) 
    group = Future.wrap(AObject.collection.group,6) 
    docs = group.call(AObject,collection, 
     ... 
     ... 
    ).wait() 
    return docs 

ответ

4

Ах ... понял. После поиска в googling и googling и нахождения чрезмерного количества комментариев по строкам «не делайте этого, используйте обратные вызовы!», Я, наконец, нашел его: используйте fibers!

Я закончил использовать библиотеку fibers-promise. Мой окончательный код выглядит примерно так:

Meteor.methods 
    getdata: -> 
    promise = __meteor_bootstrap__.require('fibers-promise') 
    mongoose = __meteor_bootstrap__.require('mongoose') 
    db = mongoose.connect(__meteor_bootstrap__.mongo_url) 
    ASchema = new mongoose.Schema() 
    ASchema.add({key: String}) 
    AObject = mongoose.model('AObject',ASchema) 
    mypromise = promise() 
    AObject.collection.group(
     ... 
     ... 
     (err,doc) -> # mongoose callback function 
     if err 
      mypromise.set new Meteor.Error(500, "my error") 
      return 
     ... 
     ... 
     mypromise.set mydesiredresults 
    ) 
    finalValue = mypromise.get() 
    if finalValue instanceof Meteor.Error 
     throw finalValue 
    return finalValue 
+1

Вы можете принять ваши собственные ответы, и я думаю, что это будет оправдано здесь. Возможно, вам сначала придется немного подождать. –

+0

Извините, что я был в восторге от мин и просто не мог с собой поделать. – dsummersl

+0

Я не жалуюсь, я предлагаю вам принять свой собственный ответ, чтобы облегчить будущим искателям решение подобных проблем. –

0

Использования волокон/будущее модуля может дать вам лучший API для Метеора, поскольку это то, что используется внутри, и он приходит с любым ванильным метеором установки.

Для того, чтобы ваш пример:

require = __meteor_bootstrap__.require 
Future = require 'fibers/future' 
mongoose = require 'mongoose' 

Meteor.methods 
    getdata: -> 
    db = mongoose.connect(__meteor_bootstrap__.mongo_url) 
    ASchema = new mongoose.Schema() 
    ASchema.add({key: String}) 
    AObject = mongoose.model('AObject',ASchema) 

    # wrap the method into a promise 
    group = Future.wrap(AObject.collection.group) 

    # .wait() will either throw an error or return the result 
    doc = group(... args without callback ...).wait() 
+0

Это звучит лучше, я попробую. – dsummersl

+0

, если вы попробуете doc = group.call (AObject.collection, ... args без обратного вызова ...). Wait() вместо doc = group (... args без обратного вызова ...). Wait(), do вы все равно получаете то же исключение? – olivoil

+0

Арг, извините за бег. Так что первая ошибка, которую я опубликовал (Object # ...), была, когда я попытался связать вызов AObject.find. Я пробовал передать AObject к этому с небольшой удачей (такая же ошибка выше). Затем я попробовал только AObject.collection.group, как я писал в сообщении, и это дает мне эту ошибку: функция ожидает не более -1 аргументов. Я попытался поставить AObject.collection в качестве аргумента и получить такую ​​же ошибку. – dsummersl

2

Заканчивать this amazing gist с коллекцией, например.

+0

как, черт возьми, это не принято в качестве ответа. + 1'd – KJW

+0

[Всегда указывайте наиболее значимую часть важной ссылки, если целевой сайт недоступен или постоянно находится в автономном режиме.] (Http://stackoverflow.com/help/how-to-answer) –

Смежные вопросы