首页 > 解决方案 > JavaScript 数组有元素但长度为零

问题描述

我在网上做了一些搜索,似乎没有什么能解决我的问题。我有以下 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"
  }
]

但是当我尝试使用 fillInOptions() 遍历每个条目时,我的循环永远不会完成,因为长度显然为零。但是,当我使用 console.log() 转储数组时,它告诉我长度为 2,并显示上面的内容。我需要能够将每个选项添加到我的下拉列表中。

谢谢!

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

标签: javascriptjqueryhtmlloops

解决方案


看起来你.forEach()是问题的根源。a 的参数forEachcurrentValue, index这样的:array.forEach(function(currentValue, index) {});但看起来你正在以相反的方式使用它们

尝试将该迭代重写为:

    ytFill.forEach(function(v, i) {
        console.log(i);
        ytdlOptions.append(new Option(v.fmt_quality, v.fmt_id));
    });

注意参数顺序vi参数的不同。


推荐阅读