在方法中返回Meteor.http结果



我有一个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块。

最新更新