从Meteor.SetTimeout中调用时访问this.userId不起作用

时间:2013-03-11 01:09:25

标签: meteor

我一直在尝试从Meteor.methods调用中访问this.userId变量,但是当我尝试通过Meteor.setTimeout或Meteor.setInterval调用该方法时,它似乎不起作用。 / p>

这就是我所拥有的:

if (Meteor.is_server) {
    Meteor.methods({
        getAccessToken : function() {
            try {
                console.log(this.userId);
                return Meteor.users.findOne({_id: this.userId}).services.facebook.accessToken;
            } catch(e) {
                return null;
            }
        }
    });

    var fetch_feed = function() {
        console.log(Meteor.call("getAccessToken"));
        [...] // A bunch of other code
    };

    Meteor.startup(function() {
        Meteor.setInterval(fetch_feed, 60000); // fetch a facebook group feed every minute
        Meteor.setTimeout(fetch_feed, 3000); // initially fetch the feed after 3 seconds
    });
}

观察终端日志,this.userId始终返回null。但是,如果我尝试从客户端或通过控制台调用该方法,它将返回正确的ID。

为什么这不能在Meteor.setInterval中起作用?这是一个错误还是我做错了什么?

2 个答案:

答案 0 :(得分:2)

Meteor userId与客户端连接相关联。服务器可以与许多客户端进行交互,并且方法内的this.userId将告诉您哪个客户端要求运行该方法。

如果服务器使用Meteor.call()运行方法,那么它将没有userId,因为它没有为任何客户端运行。

这些方法允许客户端调用在服务器上运行的函数。对于服务器将自动触发javascript函数的事情。

答案 1 :(得分:-1)

我使用了一个解决方案 - 有时你不想让方法成为一个函数但是真的希望它仍然是一个方法。在这种情况下,黑客可以做到这一点:

            var uniqueVar_D8kMWHtMMZJRCraiJ = Meteor.userId();
            Meteor.setTimeout(function() {
                    // hack to make Meteor.userId() work on next async 
                    // call to current method
                    if(! Meteor._userId) Meteor._userId = Meteor.userId;
                    Meteor.userId = function() {
                        return Meteor._userId() || uniqueVar_D8kMWHtMMZJRCraiJ
                    };
                    Meteor.apply(methodName, args);
                }
            , 100);

一些简短的解释:我们将Meteor.userId保存在Meteor._userId中,并使用返回Meteor.userId的函数覆盖Meteor._userId(),如果它为真,则为{{1}的历史值在任何这种情况发生之前。该历史值保存在一个不可能发生两次var名称的位置,以便不会发生上下文冲突。