javascript 在函数外访问数组

javascript accessing array outside of function

所以我正在为免费代码训练营制作这个 twitch.tv api 页面。 我正在尝试遍历流媒体数组并将数据推送到结果数组,按观众数排序并在页面上显示结果数组中的数据。

问题是 .append 内容在 for 循环中多次写入信息。如果我将它移出 for 循环,则变量未定义。

聪明人有什么想法吗?

    $(document).ready(function(){
    getInfo();  
    var results = [];
    function getInfo(){
        var streamers = ["FreeCodeCamp","PlayHearthstone","summit1G","BradfordLee","Savjz","Z28RyanK"];
    streamers.forEach(function(streamers){
            $.getJSON('https://wind-bow.gomix.me/twitch-api/channels' + '/' + streamers + '?callback=?', function(data){

                var name = data.display_name;
                var game = data.game;
                var logo = data.logo;

                $.getJSON('https://wind-bow.gomix.me/twitch-api/streams' + '/' + streamers + '?callback=?', function(data){
                    var status = data.stream;
                    if(data.stream == undefined){
                        status = "Offline";
                    }else{
                        status = "Online";
                    }
                    var views = data.stream;
                    if(data.stream == undefined){
                        views = 0;
                    }else{
                        views = data.stream.viewers;
                    }
                    results.push({"name": name, "logo": logo, "status": status, "game": game, "views": views});
                    results.sort(function(b, a) {return parseFloat(a.views) -parseFloat(b.views);});
                    console.log(results);
                    results.forEach(function(results){
                        $('.main').append('<div><img src="' + logo + '"><p>' + name + '</p><p>' + status + '</p><p>' + game + '</p><p>' + views + '</p></div>');
                    })                      
    }   )               
})          
            })      
        }
    });

您可以移出追加行。你说你无权访问变量,但你只是将它们存储在 results 数组中,因此你可以从那里访问它们。所以简单地移出这条线,改变是这样的:

results.forEach(function(result){
    $('.main').append('<div><img src="' + result.logo + '"><p>' + result.name + '</p><p>' + result.status + '</p><p>' + result.game + '</p><p>' + result.views + '</p></div>');
}) 

(请注意,您不应该 results.forEach(function(results){ 使用名称 results 两次,类似于 streamers。您是 运行 和 forEachresults 之上,所以每个 result(不是复数))

下面我重写了你的一段代码,修复了一些错误。在此 fiddle.

中查看实际效果
var streamers;
var streamCallsCompleted;
var results;

$(document).ready(function() {
    streamers = ["FreeCodeCamp", "PlayHearthstone", "summit1G", "BradfordLee", "Savjz", "Z28RyanK"];
    results = [];
    streamCallsCompleted = 0;

    getAndAppendInfo(streamers);

    // parseFloat shouldn't be necessary as views should be a whole number
    results.sort(function(b, a) {
        return parseInt(a.views) - parseInt(b.views);
    });


});

function getAndAppendInfo(streamers) {
    streamers.forEach(
        function(streamer) {
            $.getJSON('https://wind-bow.gomix.me/twitch-api/channels' + '/' + streamer + '?callback=?', function(data) {
            channelCallSuccess(data, streamer)
            })
                .fail(channelCallError);
        });
}

function channelCallError() {
    streamCallsCompleted++;

    checkAndAppendResults();
}

function streamCallError() {
    streamCallsCompleted++;

    checkAndAppendResults();
}

function channelCallSuccess(data, streamer) {


    var name = data.display_name;
    var game = data.game;
    var logo = data.logo;

    $.getJSON('https://wind-bow.gomix.me/twitch-api/streams' + '/' + streamer + '?callback=?', function(data) {
        streamCallsCompleted++;

        var status = data.stream ? "Online" : "Offline";
        var views = data.stream ? data.stream.viewers : 0;

        results.push({
            "name": name,
            "logo": logo,
            "status": status,
            "game": game,
            "views": views
        });

        checkAndAppendResults();
    });
}

function checkAndAppendResults() {
    if (streamCallsCompleted < streamers.length) {
        return;
    }

    console.log(results);
    results.forEach(function(result) {
        $('.main').append('<div><img src="' + result.logo + '"><p>' + result.name + '</p><p>' + result.status + '</p><p>' + result.game + '</p><p>' + result.views + '</p></div>');
    });
}

基本上,这里的要点是 getJSON 调用是异步的。这意味着这段代码没有按顺序执行。因此,我们必须跟踪我们拨打了多少电话。只有当所有调用都成功或错误时,我们才会处理结果。