2016-04-04 123 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是偉大的,使用它!