我有一个Meteor方法,它封装在http.get周围。我正试图将该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);
});
当然,在这里,会话变量最终为空
(注意,如果我在方法中用一些伪字符串硬编码返回,这部分代码似乎很好,因为它返回得很好。)
帮助?
在您的示例中,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 );
}
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
,如果同步执行,它们都必须等待彼此逐个返回。
点击此处了解更多信息。
有时异步调用更可取。为此,您可以使用async/await语法,并且需要promisify 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');
}
},
});
请注意,流星test
方法标记为async
。这允许在返回Promise
的方法调用中使用其内部的await
运算符。在解决返回的promise之前,不会执行await
运算符后面的代码行。如果承诺被拒绝,将执行catch
块。