Javascript 在方法中返回Meteor.http结果

Javascript 在方法中返回Meteor.http结果,javascript,meteor,Javascript,Meteor,我有一个Meteor方法,它围绕一个http.get。我正在尝试从该http返回结果。请进入该方法的返回,以便在调用该方法时使用结果。 但是我不能让它工作 这是我的密码: (在共享文件夹中) 出于某种原因,即使结果存在并且http调用有效,也不会返回结果:console.log(result.content);确实记录了结果 (客户端文件夹) 当然,在这里,会话变量最终是空的。 (请注意,这部分代码似乎没有问题,因为如果我在方法中使用一些伪字符串硬编码返回,它会正确返回。) 帮助?在您的示例中,

我有一个Meteor方法,它围绕一个http.get。我正在尝试从该http返回结果。请进入该方法的返回,以便在调用该方法时使用结果。
但是我不能让它工作

这是我的密码:

(在共享文件夹中)

出于某种原因,即使结果存在并且http调用有效,也不会返回结果:console.log(result.content);确实记录了结果

(客户端文件夹)

当然,在这里,会话变量最终是空的。
(请注意,这部分代码似乎没有问题,因为如果我在方法中使用一些伪字符串硬编码返回,它会正确返回。)


帮助?

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

:

HTTP.call(方法、url[、选项][、异步回调])

在服务器上,此功能可以同步运行,也可以同步运行 异步的。如果省略回调,它将同步运行并 请求成功完成后,将返回结果。如果 请求未成功,引发了一个错误

通过删除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
s,如果同步执行,它们都必须等待彼此逐个返回


更多。

有时异步调用更可取。您可以使用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');
        }
    },
});

请注意,meteor
test
方法标记为
async
。这允许在其内部使用
await
运算符和返回
Promise
的方法调用。在解析返回的承诺之前,wait运算符后面的代码行将不会执行。如果承诺被拒绝,将执行catch块。

如何在客户上实现这一点?var Future=Npm.require('fibers/Future');只有服务器的东西?如何将此添加到我的Meteor项目中?我收到一个“未定义Npm”错误
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();
    }
});
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');
        }
    },
});