【问题标题】:Meteor method returns undefined to the client (asynchronous)Meteor 方法返回 undefined 给客户端(异步)
【发布时间】:2016-07-01 16:31:44
【问题描述】:

我一直致力于将 Google Recaptcha 集成到 Meteor 和 AngularJS 网络应用程序中。一切都很顺利,直到我不得不验证 recaptcha 响应——由于某种奇怪的原因,我无法从后端获得异步响应到前端。

我尝试了很多不同的变体,并且阅读了很多关于 SO 和一般互联网的帖子,但没有运气 - 所以我选择发布我自己的问题。


这就是我正在做的事情:

客户:

Meteor.call('recaptcha.methods.validateRecaptcha', { 'response' : this.recaptcha.getResponse(this.id) }, function(error, result) {
    // error and result are both undefined
    console.log('Do something with the ' + error + ' or ' + result + '.');
}

所以,我正在调用一个 Meteor 方法并传入一个在方法完成时运行的回调。但是,errorresult 参数都是未定义的。

服务器:

run: function(data) {
    if (this.isSimulation) {
        /*
         * Client-side simulations won't have access to any of the
         * Meteor.settings.private variables, so we should just stop here.
         */
        return;
    }

    return Meteor.wrapAsync(HTTP.post)(_someUrl, _someOptions);
}

最后一行是我在几个 Meteor 指南中找到的同步/异步结构的缩短版本(我也尝试过这个版本),即:

var syncFunc = Meteor.wrapAsync(HTTP.post);
var result = syncFunc(Meteor.settings.private.grecaptcha.verifyUrl, _options);
return result;

我也尝试过使用 Futures 的版本:

var Future = Npm.require( 'fibers/future' );
var future = new Future();
var callback = future.resolver();
HTTP.post(Meteor.settings.private.grecaptcha.verifyUrl, _options, callback);

return future.wait();

现在,这里的意图是我使用Meteor.call()从客户端调用此方法,客户端存根运行(以防止模拟错误,因为我们在真正的非SO服务器中使用私有Meteor.settings变量-侧代码)并立即返回(发生),并且服务器在将结果返回给客户端(没有发生 - 回调发生但没有错误之前)点击 Google 的 Recaptcha API(发生并且服务器收到响应) /成功数据)。

我的想法是两种情况之一正在发生:

  1. 我只是做错了,我没有正确地将数据发送回客户端。
  2. 同步客户端存根(立即返回)告诉客户端服务器响应并不重要,因此它从不等待正确的异步响应。

是否有任何 Meteor 专家在这里发表意见,让我知道发生了什么以及如何让异步请求在 Meteor 应用程序中正常运行?

谢谢!

【问题讨论】:

  • 能否请您在服务器端发布完整的 Meteor 方法?它不仅仅是run: function (data) { ... }

标签: javascript angularjs node.js asynchronous meteor


【解决方案1】:

documentationHTTP.call,这是HTTP.post 的通用版本,它说

可选回调。如果通过,该方法将异步运行,而不是同步运行,并调用 asyncCallback。在客户端,这个回调是必需的。

所以,在服务器上,你可以像这样异步运行它

run: function(data) {
    if (this.isSimulation) {
        /*
         * Client-side simulations won't have access to any of the
         * Meteor.settings.private variables, so we should just stop here.
         */
        return;
    }

    // No need to pass callback on server.
    // Since this part is not executed on client, you can do this
    // Or you can use Meteor.isClient to run it asynchronously when the call is from client.
    return HTTP.post(Meteor.settings.private.grecaptcha.verifyUrl, _options);
}

【讨论】:

  • 感谢您的回复。这实际上是我第一次尝试让它工作(在所有Meteor.wrapAsync() 和期货业务之前)——但客户端仍然没有收到错误/成功数据。
  • @SamuelMS:当您在服务器上控制台记录结果时,您在服务器控制台中看到了什么。假设您想在回调中的服务器和 console.log 上异步执行它,您是否收到错误或结果?据我所知,你的wrapAsyncFuture 的东西也是正确的。我只能想到HTTP.post 成功被调用但没有数据返回给你。
  • 我收到了来自 HTTP 的响应——服务器正在正确地 POST 并接收到预期的结果(成功/失败并带有适当的输入)。将结果返回给客户端似乎确实是一个问题。
  • 不费吹灰之力,感谢您花时间研究这个问题——我特别感谢有关 futures/wrapAsync 语法的反馈,因为更多的关注可以减少它只是一个简单错误的机会。
  • 好吧,这太尴尬了——在休息了一会儿,又以新的眼光回来之后,看起来你的这个答案真的一针见血。我在服务器上传递了一个回调,因为我也想在那里做额外的工作,如果你想让客户端回调也运行,你就不能这样做。我的最终解决方案使用期货来包装 HTTP 回调,并在完成所有额外工作后解决它的承诺。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2019-05-30
  • 2017-06-25
  • 1970-01-01
  • 2020-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-26
相关资源
最近更新 更多