Метеор. Почему я должен использовать this.userId вместо Meteor.userId(), когда это возможно?

Судя по этому комментарию Дэвида Глассера в выпусках GitHub:

this.userId — это основной API, а Meteor.userId() — синтаксический сахар для пользователей, плохо знакомых с JavaScript, которые могут еще не понимать деталей успешного использования этого.

Кажется, что мы должны использовать this.userId везде, где это возможно (например, внутри функции метода, где вы можете использовать оба), и использовать только Meteor.userId() внутри функций публикации. Если это предположение верно, почему?

(Также было бы полезно обратиться к соответствующим битам кода, я не могу его найти)


person dayuloli    schedule 26.09.2015    source источник
comment
возможный дубликат Meteor.userId vs Meteor.userId()   -  person CollinD    schedule 26.09.2015
comment
@CollinD Этот вопрос касается Meteor.userId против Meteor.userId(). Этот вопрос касается this.userId против Meteor.userId()   -  person dayuloli    schedule 26.09.2015
comment
Есть ответ, который кажется актуальным. Он конкретно ссылается на ваш вопрос. Извините, если это не так.   -  person CollinD    schedule 26.09.2015
comment
@CollinD Спасибо за попытку предоставить соответствующую ссылку, но в функции метода, где вы можете использовать как this.userId, так и Meteor.userId(), зачем выбирать один вместо другого?   -  person dayuloli    schedule 26.09.2015
comment
Рассмотрим производительность как фактор. Это основная причина использования this.userId, а не Meteor.userId.   -  person Sak90    schedule 26.09.2015


Ответы (2)


Ваш вопрос, кажется, объединяет Meteor.userId() и Meteor.user(). Основная часть вопроса, кажется, спрашивает о первом, в то время как строка темы спрашивает о втором. Я постараюсь обратиться к обоим.

  1. На сервере в функции публикации вызов Meteor.userId() или Meteor.user() приведет к вызвать ошибку. Вместо этого используйте this.userId или Meteor.users.findOne(this.userId) соответственно. Однако обратите внимание, что функция публикации вызывается только тогда, когда клиент подписывается. Если вы хотите, чтобы публикация менялась при изменении записи пользователя, вам нужно observe() курсор, возвращенный Meteor.users.find(this.userId), и предпринимать соответствующие действия при изменении записи.
  2. На сервере во время обработки вызова метода Meteor.userId() и Meteor.user() будут соответствовать ID вызывающего пользователя и его записи соответственно. Однако имейте в виду, что вызовы Meteor.user() приведут к запросу БД, поскольку они фактически эквивалентен Meteor.users.findOne(Meteor.userId()).

    Непосредственно в вызове метода вы также можете использовать this.userId вместо Meteor.userId(), но вы вряд ли увидите значительную разницу в производительности. Когда сервер получает вызов метода, он запускает ваш реализация метода с идентификатором пользователя (и некоторой другой информацией), хранящейся в конкретном слот на волокне. Meteor.userId() просто извлекает идентификатор из слота на текущем волокне. Это должно быть быстро.

    Как правило, легче рефакторить код, использующий Meteor.userId(), чем this.userId, потому что вы не можете использовать this.userId вне тела метода (например, this не будет иметь свойства userId внутри функции, которую вы вызываете из тела метода), и вы не можете используйте this.userId на клиенте.

  3. На клиенте Meteor.userId() и Meteor.user() не будут выдавать ошибки, а this.userId не сработает. Вызовы Meteor.user() фактически эквивалентны Meteor.users.findOne(Meteor.userId()), но поскольку это соответствует запросу базы данных mini-mongo, производительность, вероятно, не будет проблемой. Однако из соображений безопасности объект, возвращаемый Meteor.user(), может быть неполным (особенно если пакет autopublish не установлен).
person Dean Brettle    schedule 27.09.2015
comment
Спасибо за место, я имел в виду Meteor.userId() и исправил заголовок вопроса. Все в вашем ответе достаточно ясно и подтверждает то, что я читал. Не могли бы вы немного расширить, поскольку Meteor.userId() будет работать глубже в стеке вызовов? В своем предыдущем комментарии вы сказали, что Meteor.userId() не запрашивает БД и не потребляет каких-либо значительных дополнительных ресурсов. - тогда что он делает? Я не смог найти этот фрагмент кода в исходном коде. - person dayuloli; 27.09.2015
comment
Спасибо за редактирование, хотя я не могу утверждать, что понимаю код, на который вы ссылаетесь, я немного лучше понимаю, как теперь работает Meteor.userId(). Также спасибо за альтернативную точку зрения на комментарий в вопросе, что использование Meteor.userId() может быть лучше, потому что вы можете перенести тот же код в другое место, возможно, на клиент. Еще раз спасибо за ответ. - person dayuloli; 27.09.2015

Проще говоря, Meteor.userId() запрашивает БД каждый раз, когда вы ее используете. На стороне клиента (по логике) все выглядит нормально — так как у нас есть minimongo.

На стороне сервера использование Meteor.userId() потребляет дополнительные ресурсы на СЕРВЕРЕ, что иногда нежелательно.

Теперь this.userId больше похож на переменную сеанса m, т.е. он будет иметь значение только тогда, когда к текущему сеансу присоединен идентификатор пользователя. И, следовательно, использование этой ссылки не будет каждый раз получать базу данных, а вместо этого использовать идентификатор пользователя активного сеанса.

Рассмотрим производительность как фактор. Это основная причина использования this.userId, а не Meteor.userId.

person Sak90    schedule 26.09.2015
comment
Вызов Meteor.user или Meteor.userId из функций публикации вызывает исключение. т. е. они доступны в любом месте сервера, за исключением функций публикации, в то время как this.userid доступен ВЕЗДЕ. Кроме того, ясно, что Meteor.user Meteor.userId и т. д. извлекает объект пользователя из монго (через объект Accounts) — см. github.com/meteor/meteor/blob/devel/packages/accounts-base/ - person Sak90; 26.09.2015
comment
Meteor.userId() не запрашивает БД и не потребляет значительных дополнительных ресурсов. Однако на сервере Meteor.user() работает. - person Dean Brettle; 27.09.2015