前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >客户端 Meteor.call 等待服务端异步函数返回

客户端 Meteor.call 等待服务端异步函数返回

作者头像
我与梦想有个约会
发布2023-10-20 19:35:20
2090
发布2023-10-20 19:35:20
举报
文章被收录于专栏:jiajia_dengjiajia_deng

在 Meteor 项目中,经常会有客户端使用 Meteor.call 方法去调用服务端的一个方法,并等待该方法返回。通常情况下,服务端的方法只需要 return 后,客户端使用回调函数就可以访问到 return 的值了。但如果服务端同样调用了一个异步执行的函数,那么此时就无法判断服务端的异步函数是否已经执行完毕,返回结果就会出现不准确的情况。如下所示:

服务端代码:

代码语言:javascript
复制
setWechatMenu: function (appId, appSecret, jsonMenu) {
console.log(jsonMenu);
// 创建微信菜单
var url = “https://api.weixin.qq.com/cgi-bin/token?” +
      “grant_type=client_credential&appid=” +
      appId + “&secret=” + appSecret;
Meteor.http.get(url, { timeout: 30000 }, function(err, result) {
var jsonContent = JSON.parse(result.content);
var accessToken = jsonContent.access_token;
var url = “https://api.weixin.qq.com/cgi-bin/menu/create?access\_token=“ + accessToken;
// post 创建菜单
var response = Meteor.http.post(url, { data: jsonMenu }, function(err, result) {
console.log(‘Content: ‘ + result.content);
});
return response;
});
}
客户端代码:
Meteor.call(“setWechatMenu”, appId, appSecret, json, function(error, result) {
if (!error) {
console.log(“result :”, result);
};
});

上面的例子中,我们在客户端使用 Meteor.call 方法调用了一个服务端的函数,等待服务端的异步函数 http.post 返回内容,但你会发现结果并不是那么理想,客户端在打印 result 的时候结果是 ?developer/article/2347912/undefined。这是因为服务端 http.get 和 http.post 都使用了异步回调的方式取得返回值,实际这两个函数在调用时立即就返回了。而客户端也是立即就接收到了服务器的返回,并没有真正等到 http.get 和 http.post 执行完毕。 我开始天真的认为,只要在客户端使用同步方法调用 Meteor.call 不就可以了吗?

代码语言:javascript
复制
var result = Meteor.call(“setWechatMenu”, appId, appSecret, json);

但结果告诉我,这样是不行的,后来在 Meteor 官方查询文档也说到,这样的调用是有不确定性的,也就是跟使用异步回调处理是没什么区别的。而这种同步的方法仅在服务端(On the server)是有效的:

为了解决这种问题,Meteor 的 github issues 专门有一篇文章是介绍如何解决类似问题的:https://gist.github.com/possibilities/3443021 其中最简单的一个方法如下:

代码语言:javascript
复制
setWechatMenu: function (appId, appSecret, jsonMenu) {
// 创建一个 future
var Future = Npm.require(‘fibers/future’);
var fut = new Future();
console.log(jsonMenu);
// 创建微信菜单
var url = “https://api.weixin.qq.com/cgi-bin/token?” +
      “grant_type=client_credential&appid=” +
      appId + “&secret=” + appSecret;
Meteor.http.get(url, { timeout: 30000 }, function(err, result) {
var jsonContent = JSON.parse(result.content);
var accessToken = jsonContent.access_token;
var url = “https://api.weixin.qq.com/cgi-bin/menu/create?access\_token=“ + accessToken;
// post 创建菜单
var response = Meteor.http.post(url, { data: jsonMenu }, function(err, result) {
console.log(‘Content: ‘ + result.content);
});
// 将 response 传递给 fut 的成员对象
fut.return(response);
});
// 等待 fut 被赋值后再返回
return fut.wait();
}

更多的方法可以参考上面 issues 链接。

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-11-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com