2014-01-17 4 views
1

В моем приложении meteor я пытаюсь зарегистрировать пользователя на сервере, выполнить некоторую работу и добавить некоторые дополнительные свойства к объекту пользователя, переданному в onCreateUser, а затем перейти к приветствию 'страница, специально адаптированная для нового пользователя. Использование Метеор 7.0.1 и железо-маршрутизатор (последняя)Асинхронный вызов внутри Meteor.onCreateUser hook

Мой клиент код выглядит примерно так:

код
// var userId = Meteor.registerUser(registrationOptions); 
// Router.go('/welcome/'+userId); 

сервера, как этот

// Meteor.onCreateUser(options, user){ 
// if (options.profile) user.profile = options.profile; 
    // a 3rd party method outside of Meteor 
// callToOutsideMethod(Meteor.bindEnvironment(function(e, res){ 
//  user.results = res; 
//  // do other stuff 
//  user.foo = blah; 
//  user.bar = baz; 
//  return user; 
//  }, function(err){ console.log(err); }); 

Когда я вернуть объект пользователя, я 'm ожидаем, что метеорит создаст запись, а затем зарегистрирует нового пользователя в ...

Но случается так, что экран становится все искаженным на секунду, а затем мы переходим к новому URL/приветствую/the_new_user_id '...

Но это вызывает ошибку в скрипте, где я пытаюсь получить доступ к чему-либо, кроме user_id. Глядя на Mongo cli, ни одно из новых свойств не было добавлено, даже «имя пользователя» и «токены входа» и т. Д. Не появляются у нового пользователя. И у недавно созданного пользователя есть ТОЛЬКО _id и ничего больше ... очень странно.

Любые идеи о том, что может вызвать это странное поведение?

+0

Пожалуйста, уточните название вашего вопроса, чтобы другие могли его найти, например. «Асинхронный вызов внутри Meteor.onCreateUser». Вы также должны добавить несколько тегов, попробуйте с 'account' /' users' и 'async' /' asynchronous'. – dalgard

ответ

1

В вашем коде вы ничего не возвращаете внутри onCreateUser. Внутренняя функция возвращает некоторое значение, которое тогда просто стоит там.


Решение?

Если внутренняя функция (callToOutsideMethod) является синхронным, что он, кажется, не будет, так как он использует обратные вызовы - но если это, ваши может просто поставить обратное заявление перед ним:

return callToOutsideMethod(...

Если внутренняя функция является асинхронной, необходимо возвратиться немного и, если это возможно, получить возвращаемое значение этой функции перед тем на самом деле создания пользователя. Если это невозможно, см. Ниже.


EDIT: Другие крючки

Помните, что гораздо больше, чем крючки onCreateUser существуют, и как часть the API и внутренне. Не бойтесь просматривать исходные файлы и использовать их для создания своего собственного решения; внутренняя работа Метеор относительно просты:

В случае onCreateUser крючка, она называется внутри функции Accounts.insertUserDoc, которая вызывается различными службами входа [1]. В вашем случае, вы должны иметь возможность продолжить процесс внутри insertUserDocпосле ваш асинхронный материал сделан.

Единственный способ я вижу, как с текущей API, является переопределение функции insertUserDoc (может показаться опасным, но похоже материал было сделано раньше) - что-то вдоль линий:

// Save the built-in function first 
Accounts.insertUserDocFinal = Accounts.insertUserDoc; 

Accounts.insertUserDoc = function (options, user) { 
    callToOutsideMethod(some_arguments, function (data) { 
    // Manipulate options and user objects? 

    Accounts.insertUserDocFinal(options, user); 
    }); 
}; 


[1] с опциями и объектами пользователя, которые затем передаются по адресу onCreateUser (за исключением того, что они еще не имеют свойств _id и createdAt).

+0

спасибо за ответ - проблема в следующем: мне нужны данные из объекта, используемого для создания пользователя, чтобы запустить callToOutsideMethod ..., а затем я хочу, чтобы Meteor подождал, пока не получу ответ от метода, и THEN сделаю пользователь. Итак, вы говорите, что если callToOutsideMethod является асинхронным, это невозможно сделать? – Petrov

+0

Если вы переопределите 'insertUserdoc', убедитесь, что он надежный, то есть убедитесь, что в итоге вставляется имя' insertUserDocFinal'. – dalgard

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