返回Meteor.http结果的方法

时间:2014-09-04 20:48:17

标签: javascript meteor

我有一个包围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);
  });

当然,会话变量最终为空 (注意,如果我在方法中使用一些虚拟字符串对返回进行硬编码,则代码的这一部分看起来很好,因为它会正确返回。)

帮助?

3 个答案:

答案 0 :(得分:14)

在您的示例中,Meteor.http.get是异步执行的。

See docs

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将执行阻止。