2015-04-10 3 views
0

я получил намеченное поведение, но Im путать почему ...метод Метеор возвращает нуль на клиенте, тот же метод запуск на клиенте возвращает правильное значение

У меня есть этот метод Метеора, который возвращает значение ключа документа; утверждение журнала доказывает, например:

findUserEmail: function(user_id){ 
    var user = Meteor.users.find({_id: user_id}).fetch(); 
    console.log(user[0].emails[0].address); 
    return user[0].emails[0].address; 
} 

Но когда я называю его на клиента, shared_user_email поле null:

shared_user_email: Meteor.call('findUserEmail', $(ev.target).find('[name=shared_user]').val())

НО, когда я имитировать вызов метода Метеор имитируя сервера запрос на клиенте, он возвращает значение, которое метод Метеор выше бревна:

shared_user_email: Meteor.users.find({_id: $(ev.target).find('[name=shared_user]').val()}).fetch()[0].emails[0].address

Что утеряно при переводе, когда клиент пытается вызвать метод сервера?

EDIT

Что происходит, когда я использую метод Метеора, чтобы вставить документ в мою коллекцию, поле которого опирается на методе Метеора? Я получаю undefined для моего shared_user_email поля здесь:

var newList = { 
     title: $(ev.target).find('[name=title]').val(), 
     description: $(ev.target).find('[name=description]').val(), 
     dateCreated: today.toDateString(), 
     owner: Meteor.userId(), 
     owner_email: Meteor.users.find({_id: Meteor.userId()}).fetch()[0].emails[0].address, 
     shared_user: $(ev.target).find('[name=shared_user]').val(), 
     shared_user_email: Meteor.call('find_shared_user_email', 
      $(ev.target).find('[name=shared_user]').val(), 
      function(err, user_email){ 
       return user_email; 
      }) 
    } 

    Meteor.call('addList', newList, function(err, list){ 
     return list; 
    }); 

ответ

1

На клиенте, необходимо вызвать функцию обратного вызова Meteor.call() для извлечения значения из вашего метода.

От documentation:

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

Он должен работать следующим образом:

Meteor.call(
    'findUserEmail', 
    user_id, 
    function(error, result){ 
    // 'result' here is email address from method 
    } 
); 
+0

im запутался в интуиции за волокном, если вы можете сэкономить минуту – redress

+1

Вот хорошее введение в Fibers в Meteor and Node от одного из лучших авторов с открытым исходным кодом от Meteor: https://meteorhacks.com/fibers-eventloop- и-meteor.html. Основная идея re: ваш вопрос в том, что когда вы вызываете Meteor.call() от клиента, вам нужно ждать возвращения результата. Но это не всегда сразу, а остальная часть вашего кода будет продолжать выполняться. Поэтому вам нужно вызвать функцию обратного вызова, чтобы дождаться результата. –

+0

gotcha, спасибо большое – redress

1

Код выше не работает, потому что вы не получаете асинхронный ответ от первого вызова сервера еще:

var newList = { 
    /* some code */ 
    shared_user_email: Meteor.call('find_shared_user_email', 
     $(ev.target).find('[name=shared_user]').val(), 
     function(err, user_email){ 
      /* this code is executing asynchronous */ 
      return user_email; 
     }) 
} 

/* the following call won't wait for the previous server call's completion */ 
Meteor.call('addList', newList, function(err, list){ 
    return list; 
}); 

Вместо вам необходимо сделать второй звонок только тогда, когда вы точно знаете, что первый вызов завершен, например:

var newList = { 
    /* some code */ 
}; 

Meteor.call('find_shared_user_email', 
    $(ev.target).find('[name=shared_user]').val(), 
    function(err, user_email){ 
     newList.shared_user_email = user_email; 
     Meteor.call('addList', newList, function(err, list){ 
      /* other code to handle the added list */ 
     }); 
    }) 
} 
Смежные вопросы