0

YouTube ビデオから情報を返す JavaScript 関数を書きたいと思います。具体的には、検索で取得した動画の ID と長さを json オブジェクトで取得したいと考えています。だから私はYouTube APIを見て、この解決策を思いついた:

   function getYoutubeDurationMap( query ){
        var youtubeSearchReq = "https://gdata.youtube.com/feeds/api/videos?q="+ query +
                "&max-results=20&duration=long&category=film&alt=json&v=2";
        var youtubeMap = [];
        $.getJSON(youtubeSearchReq, function(youtubeResult){
            var youtubeVideoDetailReq = "https://gdata.youtube.com/feeds/api/videos/";
            for(var i =0;i<youtubeResult.feed.entry.length;i++){
                var youtubeVideoId = youtubeResult.feed.entry[i].id.$t.substring(27);
                $.getJSON(youtubeVideoDetailReq + youtubeVideoId + "?alt=json&v=2",function(videoDetails){
                    youtubeMap.push({id: videoDetails.entry.id.$t.substring(27),runtime: videoDetails.entry.media$group.media$content[0].duration});

                });
            }
        });
        return youtubeMap;    

    }

ロジックは問題ありませんが、多くの人が既に理解しているように、この関数を呼び出すと ajax が原因で空の配列が取得されます。とにかく完全なオブジェクトを取得する方法はありますか? Deferred オブジェクトを使用する必要がありますか? 回答ありがとうございます。

4

2 に答える 2

0

youtubeMapお気づきのように、返却時点ではまだデータが取り込まれていないため、直接返却することはできません。ただし、完全に入力されたPromiseを返すことはyoutubeMapできます。これは、 eg.done(), .fail()またはで実行できます.then()

function getYoutubeDurationMap(query) {
    var youtubeSearchReq = "https://gdata.youtube.com/feeds/api/videos?q=" + query + "&max-results=20&duration=long&category=film&alt=json&v=2";
    var youtubeVideoDetailReq = "https://gdata.youtube.com/feeds/api/videos/";
    var youtubeMap = [];
    var dfrd = $.Deferred();
    var p = $.getJSON(youtubeSearchReq).done(function(youtubeResult) {
        $.each(youtubeResult.feed.entry, function(i, entry) {
            var youtubeVideoId = entry.id.$t.substring(27);
            //Build a .then() chain to perform sequential queries
            p = p.then(function() {
                return $.getJSON(youtubeVideoDetailReq + youtubeVideoId + "?alt=json&v=2").done(function(videoDetails) {
                    youtubeMap.push({
                        id: videoDetails.entry.id.$t.substring(27),
                        runtime: videoDetails.entry.media$group.media$content[0].duration
                    });
                });
            });
        });
        //Add a terminal .then() to resolve dfrd when all video queries are complete.
        p.then(function() {
            dfrd.resolve(query, youtubeMap);
        });
    });
    return dfrd.promise();
}

への呼び出しgetYoutubeDurationMap()は次の形式になります。

getYoutubeDurationMap("....").done(function(query, map) {
    alert("Query: " + query + "\nYouTube videos found: " + map.length);
});

ノート:

  • 実際には、おそらくループしてandのデータmapを表示します。.id.runtime
  • 順次クエリは、クライアントとサーバーの両方に優しく、成功する可能性が高いため、並列クエリよりも優先されます。
  • もう 1 つの有効なアプローチは、個別の promise の配列 (ビデオごとに 1 つ) を返し、完了に で応答すること$.when.apply(..)ですが、必要なデータを抽出するのはより厄介です。
于 2013-05-31T18:22:16.610 に答える