【问题标题】:Meteor.call returns 'undefined' result when the variable is defined on server当在服务器上定义变量时,Meteor.call 返回“未定义”结果
【发布时间】:2015-12-11 21:15:53
【问题描述】:

有人可以在我的代码中看到为什么变量 oauthToken 是在服务器上定义的,但在 Meteor.call 的结果中返回给客户端时却没有定义

我打电话在服务器上发起一个发布请求

正文被解析,我将一个值存储到变量 oauthToken

这会在服务器上打印出来,但不会在我的“结果”中的客户端上打印出来

这是因为客户端正在运行模拟吗?我们可以在异步函数中“返回”吗?

服务器.js

Meteor.methods({
 getGoodreads: function () { 
 request.post('http://www.goodreads.com/oauth/request_token', {oauth:{
                 consumer_key: '89hdg8pEoMzRdg',
                 consumer_secret: 'dfgdfgHthtdtjtt' }}, function (error, response, body) {
      if (!error && response.statusCode == 200) {
              var a = querystring.parse(body)
              oauthToken = a.oauth_token
              console.log(oauthToken); //prints value i need
              return oauthToken
       }else{
              console.log('there is an error ' + error);
            }
   });
} 
});

client.js

Template.profile.events({
    'click #goodreads': function (event) {
        event.preventDefault();
        Meteor.call('getGoodreads', function(error, result) {
            if (error) {
                console.log('this is an error ');
            } else {
                console.log(result); //THIS IS UNDEFINED...possibilities?
            }
        });
    }
 });

【问题讨论】:

  • 方法是否只定义在服务器上?如果我没记错的话,必须在客户端和服务端都定义
  • 只有当您想要延迟补偿时,上述情况才可能成立
  • 服务器请求是异步的,所以方法实际上是立即返回的。这看起来像是 this question 的副本。
  • 您最好将请求的结果放入发布中,然后在客户端订阅发布。

标签: node.js post asynchronous methods meteor


【解决方案1】:

使用期货从异步函数中返回值:

var Future = Npm.require("fibers/future")    
Meteor.methods({
     getGoodreads: function () { 
     var f = new Future();
     request.post('http://www.goodreads.com/oauth/request_token', {oauth:{
                     consumer_key: '89hdg8pEoMzRdg',
                     consumer_secret: 'dfgdfgHthtdtjtt' }}, function (error, response, body) {
          if (!error && response.statusCode == 200) {
                  var a = querystring.parse(body)
                  oauthToken = a.oauth_token
                  console.log(oauthToken); //prints value i need
                  return f.return(oauthToken)
           }else{
                  f.throw(error);
                  console.log('there is an error ' + error);
                }
       });
       return f.wait()
    } 
    });

【讨论】:

  • 我以前从未使用过future,但是内部回调中的每个路径不是都需要执行f.return()吗?我的意思是,未来正在等待某些事情发生......
  • @Christain - 我在 2.3.1 版本中添加了 'future' 并在您编写 'var future = Npm.require("fibers/future")' 时将包调用到我的项目中......并且这行得通。 oauthToken 被传递回客户端并在结果中定义!谢谢
  • 我正在从客户端调用该方法,当我使用返回值解析f 时,我总是得到未定义。我想我无法收到来自服务器的客户端承诺?
【解决方案2】:

这是因为你在方法体中启动了一个异步请求。该方法立即返回,请求的回调实际上没有任何地方可以返回结果。

我真的不知道如何使用方法来做到这一点,但你可以通过发布/订阅来做到这一点。像这样的:

服务器.js

var result = "";

Meteor.setInterval(function() {
    request.post('http://www.goodreads.com/oauth/request_token', {oauth:{
            consumer_key: '89hdg8pEoMzRdg',
            consumer_secret: 'dfgdfgHthtdtjtt' }},
        function(error, response, body) {
            if (!error && response.statusCode == 200) {
                var a = querystring.parse(body);
                oauthToken = a.oauth_token;
                result = oauthtoken;
            }
        });
    });
}, 10*1000);

Meteor.publish("goodReads", function() {
    this.added("goodReads", 1, {reads: result});
    Meteor.setInterval(function() {
        this.changed("goodReads", 1, {reads: result});
    }, 10*1000);
    this.ready();
});

客户端.js

goodReads = new Meteor.Collection("goodReads");
Meteor.subscribe("goodReads"); // May be done in waitOn in the router

这是从我的头顶上取下来的,未经测试。它可能有效,也可能无效,但至少是一个指向您如何做到这一点的指针

【讨论】:

  • 我会试试这个 Suppen
猜你喜欢
  • 1970-01-01
  • 2019-01-25
  • 2015-07-02
  • 2020-08-21
  • 2016-11-04
  • 1970-01-01
  • 2017-06-08
  • 2020-05-28
  • 1970-01-01
相关资源
最近更新 更多