$ .getJSON,$ .each和变量范围

时间:2012-03-13 15:41:37

标签: jquery ajax scope each getjson

我整天都在浏览论坛,但我并没有把它弄清楚。

我正在调用Justin.TV-API来显示我的“跟随”流的列表,然后进行嵌套调用以检查其中哪一个在线。

以下是我想要使用的代码:

//Get Favorites as Object "favs"
        var viewers;
        $.getJSON('http://api.justin.tv/api/user/favorites/hubschrauber.json?jsonp=?', function(favs) {
            $.each(favs, function(key, value) {
                //For every Object, check if user is referenced in stream and therefore online
                $.getJSON('http://api.justin.tv/api/stream/list.json?channel=' + favs[key].login + '&jsonp=?', function(streams) {
                    viewers = streams[0].channel_count;
                });
                $('#result').append(favs[key].title + ' ' + key + ': ' + favs[key].login + ' (' + viewers + ') Viewers<br />');
            });
        });

然后我遇到了getJSON和asychronisation的问题并重写了我的脚本几次:

首先这样(替换$ .each):

//Get Favorites as Object "favs"
        var viewers;
        $.getJSON('http://api.justin.tv/api/user/favorites/hubschrauber.json?jsonp=?', function(favs) {
            for (var key in favs) {
                //For every Object, check if user is referenced in stream and therefore online
                $.getJSON('http://api.justin.tv/api/stream/list.json?channel=' + favs[key].login + '&jsonp=?', function(streams) {
                    viewers = streams[0].channel_count;
                });
                $('#result').append(favs[key].title + ' ' + key + ': ' + favs[key].login + ' (' + viewers + ') Viewers<br />');
            }
        });

然后像这样(用非异步ajax替换getJSON):

var favs;
        var streams;
        var viewers;
        $.ajax({
            url: 'http://api.justin.tv/api/user/favorites/hubschrauber.json?jsonp=?',
            async: false,
            dataType: 'json',
            success: function(favs) {
                for (var key in favs) {
                    $.ajax({
                        url: 'http://api.justin.tv/api/stream/list.json?channel=' + favs[key].login + '&jsonp=?',
                        async: false,
                        dataType: 'json',
                        success: function(streams) {
                            viewers = streams[0].channel_count;
                        }
                    });
                    $('#result').append(favs[key].title + ': ' + favs[key].login + ' (' + viewers + ') Viewers<br />');
                }
            }
        });

在任何情况下,我都无法传递viewers-variable(在嵌套的api-call中编写以确定流是否在线以及它有多少个查看者)

$('#result').append(favs[key].title + ': ' + favs[key].login + ' (' + viewers + ') Viewers<br />');

我的输出始终未定义:

Day[9]: day9tv (undefined) Viewers
FollowGrubby: followgrubby (undefined) Viewers
OneMoreGame.TV: onemoregametv (undefined) Viewers

我已经使用追加和警报进行了多项检查 - JSON响应有效。

谁能帮助我?

非常感谢你的时间。

1 个答案:

答案 0 :(得分:3)

Ajax是异步的,在填充后需要访问viewers变量的任何东西都需要在ajax请求的完整回调中。

延迟对象将成为这里的方式,我将制作一个小型演示。

更新:
http://jsfiddle.net/cMKkQ/

不需要延迟对象,只需重新构建一点。

//Get Favorites as Object "favs"
$.getJSON('http://api.justin.tv/api/user/favorites/hubschrauber.json?jsonp=?', function(favs) {
    $.each(favs, function(key, value) {
        //For every Object, check if user is referenced in stream and therefore online
        $.getJSON('http://api.justin.tv/api/stream/list.json?channel=' + favs[key].login + '&jsonp=?', function(streams) {
            $('#result').append(value.title + ' ' + key + ': ' + value.login + ' (' + streams[0].channel_count + ') Viewers<br />');
        });
    });
});

更新:
另一种方法:

var favorites = [];
function processFavorites () {
    $("#result").empty();
    $.each(favorites,function(index,obj){
        // here we populate the results div
        $('#result').append(obj.title + ' ' + index + ': ' + obj.login + ' (' + obj.viewers + ') Viewers<br />');
    });
}
function getFavorites () {
    favorites = [];
    $.getJSON('http://api.justin.tv/api/user/favorites/hubschrauber.json?jsonp=?', function(favs) {
        var defArr = [];
        $.each(favs, function(key, value) {
            //For every Object, check if user is referenced in stream and therefore online
            defArr.push($.getJSON('http://api.justin.tv/api/stream/list.json?channel=' + favs[key].login + '&jsonp=?', function(streams) {
                favorites.push({title:value.title,key:key,login:value.login,viewers:streams[0].channel_count});
            }));
        });
        $.when.apply($,defArr).always(function(){
            processFavorites();
        });
    });
}
// this runs the process of getting and processing favorites. Run it when you want.
getFavorites();​

但是,Feed目前没有返回结果,我认为它与此代码无关。

http://jsfiddle.net/cMKkQ/3/