此Meteor服务器代码尝试在公共方法“sendEmail”中使用Meteor.userId(),但有时我会收到错误
错误Meteor.userId只能在方法调用中调用。使用this.userId
lib = (function () {
return Object.freeze({
'sendEmail': function(msg){
let userId = Meteor.userId();
//do stuff for this user
},
'otherPublicMethod': function(){
//do other things then use sendEmail
lib.sendEmail(); // <---- Error Meteor.userId can only be invoked in method calls. Use this.userId
}
});
}());
// Now I call sendEmail from any where, or can I?
Meteor.methods({
'sendEmail': (msg) => {
lib.sendEmail(msg); // <---- NO error when this is called
},
});
如何修复? THX
答案 0 :(得分:1)
如果从任何异步方法调用lib.sendEmail,请确保绑定Meteor环境 例如检查下面模拟异步行为的代码
lib = (function () {
return Object.freeze({
'sendEmail': function (msg) {
let userId = Meteor.userId();
console.log(userId);
//do stuff for this user
},
'otherPublicMethod': function () {
//do other things then use sendEmail
lib.sendEmail(); // <---- Error Meteor.userId can only be invoked in method calls. Use this.userId
}
});
}());
// Now I call sendEmail from any where, or can I?
Meteor.methods({
'sendEmail': (msg) => {
//simulate async behaviour + bind environment
Meteor.setTimeout(Meteor.bindEnvironment(function () {
lib.sendEmail(msg); // <---- NO error when this is called
}));
//output :
// null - if user has not logged in else
// actual userId - if user is loggedin
//simulate async behaviour without binding environment
Meteor.setTimeout(function () {
lib.sendEmail(msg); // <---- error when this is called
});
//output :
// Exception in setTimeout callback: Error: Meteor.userId can only be invoked in method calls. Use this.userId in publish functions.
},
});
答案 1 :(得分:0)
我会轻轻地建议您替换IIFE的使用。相反,您可以利用ES16 modules来定义常用功能。
正如您所指出的,Meteor.userId()在方法调用中可用,但在服务器上的独立函数中不可用。当从方法调用调用这些函数时,我使用的模式是传入userId(或实际用户)。 e.g。
进口/ API /电子邮件/服务器/ utils的/ emailUtils.js:
const SendEmail = function(userId, msg) {
// do stuff
};
export {SendEmail};
进口/ API /电子邮件/服务器/ emailMethods.js:
import {SendEmail} from '/imports/api/email/server/utils/emailUtils';
Meteor.methods({
'sendEmail': (msg) => {
check(msg, String);
// other security checks, like user authorization for sending email
SendEmail(Meteor.userId(), msg);
},
});
现在,您可以使用任何方法或发布来调用可重复使用的SendEmail函数。此外,通过遵循此模式,您距离创建可测试代码更近了一步。也就是说,测试一个注入userId的函数比模拟“this.userId”或“Meteor.userId()”更容易。