2016-04-04 81 views
1

有一个简单的字段输入一个YouTube的ID。我使用的是renaldo的YouTube YouTube(https://atmospherejs.com/renaldo/youtube-api)来检索YouTube剪辑的标题。为什么我的Meteor.method返回undefined?

客户端事件将track ID(var tid)值成功传递给方法'addTrack' - 它将曲目的标题输出到服务器上的控制台。我真的很难把所有东西都还给客户。

如果我从'addTrack'方法调用'getVideoData'方法,它每次仍然返回'undefined'。我不是流星或JavaScript专家,这只是我正在学习的东西而已。

我理解回调的概念和javascript的同步性质(我认为!)。

谢谢。

[EDIT下面的代码解决我的问题,使用未来]

if (Meteor.isServer) { 

    YoutubeApi.authenticate({ 
    type: 'key', 
    key: API_KEY 
    }); 

Meteor.methods({ 
    addTrack: function(tid) { 

    Meteor.call("getVideoData", tid, function(err,res) { 

    console.log(res); 

    }); 
    }, 
    getVideoData: function(tid) { 
    var future = new Future(); 

    YoutubeApi.videos.list({ 
    part: "snippet", 
    id: tid, 
    }, function (err,data) { 
     var _data = {"title":data.items[0].snippet.title,"desc":data.items[0].snippet.description}; 
     future["return"](_data) 

    }); 
    return future.wait(); 

} 

Meteor.startup(函数(){ 未来= Npm.require( '纤维/未来');

} ); }

+0

这是一个非常常见的流星问题,有几个可能的解决方案。基本问题是你的方法正在调用一个异步函数。 –

+0

你如何从其他方法调用方法“getVideoData”,你是否使用Meteor.call(“getVideoData”)? – Zafta

+0

是的,我通过Meteor.call(“getVideoData”)从另一个方法调用该方法,但仍然未定义。 – rick

回答

2

流星方法很棘手,因为他们使用Fibers是同步的(当然,它们在开发者看来是同步的)。所以你需要使用Meteor.wrapAsync()来包装所有的YoutubeApi。我没有测试过下面的代码,但它应该是这个样子:

Meteor.methods({ 
    getVideoData: function(tid) { 
    var syncYT = Meteor.wrapAsync(YoutubeApi.videos.list); 
    var data = syncYT({part: "snippet",id: tid,}); 
    var transformed = {"title":data.items[0].snippet.title,"desc":data.items[0].snippet.description}; 

    console.log(transformed.title); 
    return transformed.title; 
    } 
}); 

你想了解更多有关错误在这种情况下处理,但这应该让你去。请记住,客户端Meteor始终是异步的,而服务器端可选地是异步的。使用wrapAsync或Futures来处理方法中的异步需求。

最后,Meteor guide是伟大的,使用它!