JavaScript数组有元素,但长度为零

JavaScript数组有元素,但长度为零,javascript,jquery,html,loops,Javascript,Jquery,Html,Loops,我在网上做了一些搜索,但似乎没有什么能解决我的问题。我有以下jQuery代码: function youtube_data_parser(data) { //---> parse video data - start var qsToJson = function(qs) { var res = {}; var pars = qs.split('&'); var kv, k, v; for (i in

我在网上做了一些搜索,但似乎没有什么能解决我的问题。我有以下jQuery代码:

function youtube_data_parser(data) {
    //---> parse video data - start
    var qsToJson = function(qs) {
        var res = {};
        var pars = qs.split('&');
        var kv, k, v;
        for (i in pars) {
            kv = pars[i].split('=');
            k = kv[0];
            v = kv[1];
            res[k] = decodeURIComponent(v);
        }
        return res;
    }
    //---> parse video data - end

    var get_video_info = qsToJson(data);

    if (get_video_info.status == 'fail') {
        return {
            status: "error",
            code: "invalid_url",
            msg: "check your url or video id"
        };

    } else {
        // remapping urls into an array of objects

        //--->parse > url_encoded_fmt_stream_map > start

        //will get the video urls
        var tmp = get_video_info["url_encoded_fmt_stream_map"];
        if (tmp) {
            tmp = tmp.split(',');
            for (i in tmp) {
                tmp[i] = qsToJson(tmp[i]);
            }
            get_video_info["url_encoded_fmt_stream_map"] = tmp;
        }
        //--->parse > url_encoded_fmt_stream_map > end


        //--->parse > player_response > start
        var tmp1 = get_video_info["player_response"];
        if (tmp1) {
            get_video_info["player_response"] = JSON.parse(tmp1);
        }
        //--->parse > player_response > end

        //--->parse > keywords > start
        var keywords = get_video_info["keywords"];
        if (keywords) {
            key_words = keywords.replace(/\+/g, ' ').split(',');
            for (i in key_words) {
                keywords[i] = qsToJson(key_words[i]);
            }
            get_video_info["keywords"] = {
                all: keywords.replace(/\+/g, ' '),
                arr: key_words
            };
        }
        //--->parse > keywords > end

        //return data
        return {
            status: 'success',
            raw_data: qsToJson(data),
            video_info: get_video_info
        };
    }
}

function getVideoInfo() {

    var get_video_url = $('#ytdlUrl').val();

    var get_video_id = getUrlVars(get_video_url)['v'];

    var video_arr_final = [];

    var ajax_url = "video_info.php?id=" + get_video_id;

    $.get(ajax_url, function(d1) {

        var data = youtube_data_parser(d1);


        var video_data = data.video_info;

        var player_info = data.video_info.player_response;

        var video_title = player_info.videoDetails.title.replace(/\+/g, ' ');

        var fmt_list = video_data.fmt_list.split(',');

        var video_thumbnail_url = video_data.thumbnail_url;

        var video_arr = video_data.url_encoded_fmt_stream_map;

        //create video file array
        $.each(video_arr, function(i1, v1) {
            var valueToPush = {};
            valueToPush.video_url = v1.url;
            valueToPush.video_thumbnail_url = video_thumbnail_url;
            valueToPush.video_title = video_title;

            $.each(fmt_list, function(i2, v2) {
                var fmt = v2.split('/');
                var fmt_id = fmt[0];
                var fmt_quality = fmt[1];
                if (fmt_id == v1.itag) {
                    valueToPush.fmt_id = fmt_id;
                    valueToPush.fmt_quality = fmt_quality;
                }
            });

            video_arr_final.push(valueToPush);
        });
    });
    return video_arr_final;
}

function getUrlVars(url) {
    var vars = {};
    var parts = url.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, key, value) {
        vars[key] = value;
    });
    return vars;
}

function fillInOptions(ytOptions) {
    //console.log(ytOptions);
    //alert(ytOptions[0]);
    var ytFill = ytOptions;
    console.log(ytFill);
    //ytFill.forEach(function(i,v) {

    var ytdlOptions = $('#ytdlOptions');
    ytFill.forEach(function(i,v) {
        console.log(i);
        ytdlOptions.append(new Option(v.fmt_quality, v.fmt_id));
    });
    return true;
}


function showYTDLLoader() {
    $('#ytdlInput').fadeOut(1000, function() {
        $('#ytdlLoader').fadeIn(500);
    });
    var options = getVideoInfo();
    //console.log(options);

    if (fillInOptions(options) == true) {
        //do rest
    }
}

function showYTDLOptions() {
    return true;
}

function startDownload() {
    showYTDLLoader();
}

function hideYTDLLoader() {
    $('#ytdlLoader').fadeOut(500);
}

function animateCSS(element, animationName, callback) {
    const node = $(element);
    node.addClass(animationName);

    function handleAnimationEnd() {
        node.removeClass(animationName);
        node.animationend = null;

        if (typeof callback === 'function') callback();
    }

    node.animationend = handleAnimationEnd();
}
单击我的按钮时,我调用showYTDLLoader(),它从YouTube API获取一个对象数组,如下所示:

[
  {
    "video_url": "https://r7---sn-uxanug5-cox6.googlevideo.com/videoplayback?expire=1572496003&ei=Iw66Xa24H8PL3LUPiN25mAs&ip=2001%3A8003%3A749b%3Aa01%3A5cd8%3Ac610%3A6402%3Ad0fe&id=o-ADsVnoOoBQ6-SWzYZU7gHES06s7xQptJG6hn9WcakITY&itag=22&source=youtube&requiressl=yes&mm=31%2C29&mn=sn-uxanug5-cox6%2Csn-ntqe6n7r&ms=au%2Crdu&mv=m&mvi=6&pl=39&initcwndbps=1655000&mime=video%2Fmp4&ratebypass=yes&dur=917.768&lmt=1572418007364260&mt=1572474311&fvip=4&fexp=23842630&c=WEB&txp=5535432&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cmime%2Cratebypass%2Cdur%2Clmt&sig=ALgxI2wwRgIhAIp-4gyUTLoXFetbY0ha_YnR7DJqsp_MNjjIxqDdfPZJAiEA_WPd21jgX9broBcigf8rcSEVoJb2_NX7t3XZQqytsSM%3D&lsparams=mm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AHylml4wRAIgacvP3zjEq-rVEZFrX7a_hC6TR-Zab7Ii-Fbaupjs_PcCIHdZht4l4ioYL3ERz7WNiSbnOnhm5iYxEECaQXPP2hUp",
    "video_title": "Arnold Schwarzenegger on Son-in-law Chris Pratt, Pranking Sylvester Stallone & Terminator’s Return",
    "fmt_id": "22",
    "fmt_quality": "1280x720"
  },
  {
    "video_url": "https://r7---sn-uxanug5-cox6.googlevideo.com/videoplayback?expire=1572496003&ei=Iw66Xa24H8PL3LUPiN25mAs&ip=2001%3A8003%3A749b%3Aa01%3A5cd8%3Ac610%3A6402%3Ad0fe&id=o-ADsVnoOoBQ6-SWzYZU7gHES06s7xQptJG6hn9WcakITY&itag=18&source=youtube&requiressl=yes&mm=31%2C29&mn=sn-uxanug5-cox6%2Csn-ntqe6n7r&ms=au%2Crdu&mv=m&mvi=6&pl=39&initcwndbps=1655000&mime=video%2Fmp4&gir=yes&clen=44248820&ratebypass=yes&dur=917.768&lmt=1572416976690256&mt=1572474311&fvip=4&fexp=23842630&c=WEB&txp=5531432&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cmime%2Cgir%2Cclen%2Cratebypass%2Cdur%2Clmt&sig=ALgxI2wwRQIhANTZJlBHFWQWCnfK11yvLiPUV26c6NzvqIMKjDwmsByMAiBUSy0ZJMo4GdHSiRU4xBDDLxLtzwKZAqAKCiB-1aViDQ%3D%3D&lsparams=mm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AHylml4wRAIgacvP3zjEq-rVEZFrX7a_hC6TR-Zab7Ii-Fbaupjs_PcCIHdZht4l4ioYL3ERz7WNiSbnOnhm5iYxEECaQXPP2hUp",
    "video_title": "Arnold Schwarzenegger on Son-in-law Chris Pratt, Pranking Sylvester Stallone & Terminator’s Return",
    "fmt_id": "18",
    "fmt_quality": "640x360"
  }
]
但是,当我尝试使用FillOnOptions()遍历每个条目时,我的循环永远不会完成,因为长度显然为零。但是,当我使用console.log()转储数组时,它告诉我长度是2,并显示上面的内容。我需要能够添加每个选项到我的下拉列表

谢谢


更新:添加了完整的代码,对不起

看起来您的
.forEach()
是问题的根源。是
currentValue,index
如下:
array.forEach(函数(currentValue,index){})但看起来您正以相反的方式使用它们

尝试将该迭代重写为:

ytFill.forEach(函数(v,i){
控制台日志(i);
附加(新选项(v.fmt_质量,v.fmt_id));
});

请注意参数中
v
i
的顺序不同。

看起来您的
。forEach()
是问题的根源。是
currentValue,index
如下:
array.forEach(函数(currentValue,index){})但看起来您正以相反的方式使用它们

尝试将该迭代重写为:

ytFill.forEach(函数(v,i){
控制台日志(i);
附加(新选项(v.fmt_质量,v.fmt_id));
});

注意参数中
v
i
的顺序不同。

哪一行从YouTube获取数组,并且您是否在该位置记录了返回值?异步javascript api调用可能会显示什么
console.log(i)
控制台日志(v)?哪一行从YouTube获取数组,并且您在该位置记录了返回值?异步javascript api调用可能会显示什么
console.log(i)
控制台日志(v)?谢谢,但当我用您建议的改进修复代码时,问题仍然存在。我的完整代码在更新后的帖子中,谢谢,但是当我用您建议的改进修复代码时,问题仍然存在。我的完整代码在更新后的帖子中