jQuery - 异步执行

时间:2011-10-12 11:16:35

标签: jquery ajax json

我需要通过AJAX对YouTube API进行多次调用,以检索JSON格式的检索视频信息。

每个调用都可以同步处理,但是一旦收到所有数据,就需要对其进行处理\显示。

如何确保在收到所有数据之前未调用处理功能?我目前的解决方案是以递归方式调用AJAX函数,但我觉得有更好的解决方案。

任何帮助都会受到很大的抨击。

    var categoryWrapper,categories;
    var catCnt=0;

    function initialiseVideoLibrary() {
        categories=new Array("health","hiv","education","volunteering");
        getYouTubeData();
    }

    function getYouTubeData() {

        ytJsonUrl = "https://gdata.youtube.com/feeds/api/users/vsomediauk/uploads/-/" + categories[catCnt] + "?v=2&alt=jsonc&max-results=5&orderby=relevance";

        $.ajax({
            type: "GET",
            url: ytJsonUrl,
            cache: false,
            dataType:'jsonp',
            success: function(ytJsonResponse){
                if (catCnt < categories.length) {
                showCategory(categories[catCnt],ytJsonResponse);
                    getYouTubeData();
                    catCnt++;
                } else {
                    tabVideos();
                }
            }

        });
    }

    function showCategory(cat,ytResponse) {

        categoryWrapper = $('<div></div>').addClass('category');

        $(categoryWrapper).append($('<h3></h3>').text(cat));

        contentDiv = $('<div></div>').addClass('content');

        $.each(ytResponse.data.items,function(i,video) {
            videoWrapper = $('<div></div>').addClass('video');
            $(videoWrapper).append($('<p></p>').text(video.id));
            $(videoWrapper).append($('<p></p>').text(video.title));
            $(videoWrapper).append($('<img></img>').attr('src',video.thumbnail.sqDefault));
            $(contentDiv).append(videoWrapper);
        });

        $(categoryWrapper).append(contentDiv);
        $("#videolist").append(categoryWrapper);

    }

    function tabVideos() {
        $("#videolist").tabulation({tabAlignment : "right", titleTag : "h3", tabPosition : "top"});
    }

4 个答案:

答案 0 :(得分:2)

这对jQuery.Deferred非常有用。

只需将调用的返回值存储到jQuery.ajax,然后将其传递给jQuery.when

编辑:正如我刚刚注意到文档中没有明显的那样,我想我会注意到你可以使用以下语法将deferred的数组传递给when

$.when.apply(null, ajaxReturnValueArray).then(function() {
    tabVideos(); // Assuming this is the method you wanted to call
});

答案 1 :(得分:0)

我不确定,但您可以尝试以下更改:

function getYouTubeData() {

    ytJsonUrl = "https://gdata.youtube.com/feeds/api/users/vsomediauk/uploads/-/" + categories[catCnt] + "?v=2&alt=jsonc&max-results=5&orderby=relevance";

    $.ajax({
        type: "GET",
        url: ytJsonUrl,
        cache: false,
        async: false,
        dataType:'jsonp',
        success: function(ytJsonResponse){
            if (catCnt < categories.length) {
            showCategory(categories[catCnt],ytJsonResponse);
                getYouTubeData();
                catCnt++;
            } else {
                tabVideos();
            }
        }

    });
}

答案 2 :(得分:0)

查看.ajaxStop(),这样的内容可能有用(抱歉,未经测试!)

var categoryWrapper,categories;

function initialiseVideoLibrary() {
    categories=new Array("health","hiv","education","volunteering");
    getYouTubeData();
}

function getYouTubeData() {

        $.each(categories, function(index, value) {
            ytJsonUrl = "https://gdata.youtube.com/feeds/api/users/vsomediauk/uploads/-/" + value + "?v=2&alt=jsonc&max-results=5&orderby=relevance";

            $.ajax({
                type: "GET",
                url: ytJsonUrl,
                cache: false,
                dataType:'jsonp',
                success: function(ytJsonResponse){
                    showCategory(value,ytJsonResponse);
                }

            });
        });
}

function showCategory(cat,ytResponse) {

    categoryWrapper = $('<div></div>').addClass('category');

    $(categoryWrapper).append($('<h3></h3>').text(cat));

    contentDiv = $('<div></div>').addClass('content');

    $.each(ytResponse.data.items,function(i,video) {
        videoWrapper = $('<div></div>').addClass('video');
        $(videoWrapper).append($('<p></p>').text(video.id));
        $(videoWrapper).append($('<p></p>').text(video.title));
        $(videoWrapper).append($('<img></img>').attr('src',video.thumbnail.sqDefault));
        $(contentDiv).append(videoWrapper);
    });

    $(categoryWrapper).append(contentDiv);
    $("#videolist").append(categoryWrapper);
}

$("#videolist").ajaxStop(function() {
    $(this).tabulation({tabAlignment : "right", titleTag : "h3", tabPosition : "top"});
});

答案 3 :(得分:0)

我认为最干净的方法是让ajax调用同步,然后在for循环中依次调用getYouTubeData()。

getYouTubeData()应为:

function getYouTubeData(cat) {

    ytJsonUrl = "https://gdata.youtube.com/feeds/api/users/vsomediauk/uploads/-/" +cat+ "?v=2&alt=jsonc&max-results=5&orderby=relevance";

    $.ajax({
        type: "GET",
        url: ytJsonUrl,
        cache: false,
        async: false, //this is to make tha ajax call synchronous
        dataType:'jsonp',
        success: function(ytJsonResponse){
            showCategory(cat,ytJsonResponse);
        }
    });
}

你可以调用它:

for (var iC = 0; iC < categories.length; iC++){
    getYouTubeData(categories[iC]);
}
tabVideos();

这样,在对getYouTubeData()的所有调用完成后,将调用tabVideos()。