$ .getJSON, $ .each и область видимости переменной - PullRequest
1 голос
/ 13 марта 2012

Я просматриваю форумы весь день, но не пойму.

Я вызываю 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 и асинхронизацией и пару раз переписал свой скрипт:

сначала вот так (заменив $ .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 />');
            }
        });

затем вот так (замена getJSON не-асинхронным ajax):

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 />');
                }
            }
        });

Ни в коем случае я не могу передать переменную зрителей (которая записана во вложенном api-вызове, чтобы определить, подключен ли поток и сколько у него зрителей) в

$('#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 Ответ

3 голосов
/ 13 марта 2012

Ajax является асинхронным, все, что нуждается в доступе к переменной viewers после его заполнения, должно быть внутри полного обратного вызова запроса ajax.

Отсюда следует использовать отложенные объекты, i 'Я создам небольшую демонстрацию.

Обновление:
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();​

однако каналы в настоящее время не возвращают результатов, я не думаю, что это связано с этим кодом.

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

...