Асинхронный вызов внутри Meteor.onCreateUser hook

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

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

// 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); });

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

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

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

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

1 ответ

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

Решение?

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

return callToOutsideMethod(...

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

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

Помните, что существует гораздо больше крючков, чем onCreateUser, как часть 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).

licensed under cc by-sa 3.0 with attribution.