我有一个包围http.get的Meteor方法。我试图将http.get中的结果返回到方法的返回中,以便在调用方法时可以使用结果。
我不能让它发挥作用。
这是我的代码:
(在共享文件夹中)
Meteor.methods({
getWeather: function(zip) {
console.log('getting weather');
var credentials = {
client_id: "string",
client_secret: "otherstring"
}
var zipcode = zip;
var weatherUrl = "http://api.aerisapi.com/places/postalcodes/" + zipcode + "?client_id=" + credentials.client_id + "&client_secret=" + credentials.client_secret;
weather = Meteor.http.get(weatherUrl, function (error, result) {
if(error) {
console.log('http get FAILED!');
}
else {
console.log('http get SUCCES');
if (result.statusCode === 200) {
console.log('Status code = 200!');
console.log(result.content);
return result.content;
}
}
});
return weather;
}
});
出于某种原因,这不会返回结果,即使它们存在并且http调用正常工作: console.log(result.content); 确实记录了结果
(客户端文件夹)
Meteor.call('getWeather', somezipcode, function(error, results) {
if (error)
return alert(error.reason);
Session.set('weatherResults', results);
});
当然,会话变量最终为空 (注意,如果我在方法中使用一些虚拟字符串对返回进行硬编码,则代码的这一部分看起来很好,因为它会正确返回。)
帮助?
答案 0 :(得分:14)
在您的示例中,Meteor.http.get
是异步执行的。
HTTP.call(method,url [,options] [,asyncCallback])
在服务器上,此功能可以同步运行,也可以同时运行 异步。如果省略回调,它将同步运行 请求成功完成后返回结果。如果 请求未成功,抛出错误
通过删除asyncCallback切换到同步模式:
try {
var result = HTTP.get( weatherUrl );
var weather = result.content;
} catch(e) {
console.log( "Cannot get weather data...", e );
}
答案 1 :(得分:2)
Kuba Wyrobek是正确的,但你仍然可以异步调用HTTP.get
并使用future来停止方法返回,直到get
响应:
var Future = Npm.require('fibers/future');
Meteor.methods({
getWeather: function(zip) {
console.log('getting weather');
var weather = new Future();
var credentials = {
client_id: "string",
client_secret: "otherstring"
}
var zipcode = zip;
var weatherUrl = "http://api.aerisapi.com/places/postalcodes/" + zipcode + "?client_id=" + credentials.client_id + "&client_secret=" + credentials.client_secret;
HTTP.get(weatherUrl, function (error, result) {
if(error) {
console.log('http get FAILED!');
weather.throw(error);
}
else {
console.log('http get SUCCES');
if (result.statusCode === 200) {
console.log('Status code = 200!');
console.log(result.content);
weather.return(result);
}
}
});
weather.wait();
}
});
在这种情况下,这个方法在同步get
上没有太大的优势,但是如果你曾在服务器上做过某些事情,可以从像异步运行的HTTP调用中获益(因此不会阻塞)您的方法中的其余代码),但您仍然需要等待该调用返回方法之前,然后这是正确的解决方案。一个例子是你需要执行多个非偶然的get
,如果同步执行,它们都必须等待彼此逐一返回。
更多here。
答案 2 :(得分:0)
有时异步调用更可取。您可以使用async / await语法,并且需要宣传HTTP.get
。
import { Meteor } from 'meteor/meteor';
import { HTTP } from 'meteor/http';
const httpGetAsync = (url, options) =>
new Promise((resolve, reject) => {
HTTP.get(url, options, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
Meteor.methods({
async 'test'({ url, options }) {
try {
const response = await httpGetAsync(url, options);
return response;
} catch (ex) {
throw new Meteor.Error('some-error', 'An error has happened');
}
},
});
请注意,meteor test
方法标记为async
。这允许在其中使用await
运算符和返回Promise
的方法调用。在解决返回的promise之前,await
运算符后面的代码行不会被执行。如果拒绝承诺catch
将执行阻止。