简体   繁体   English

无法在for循环内使用Javascript添加到数组

[英]Can't add to an array with Javascript inside a for loop

I'm trying to write some code to find all the linked images on a webpage. 我正在尝试编写一些代码来查找网页上的所有链接图像。 So far I'm able to generate an array of all the links (imageLinks) but in the code below the final console.log(linkedImages) always shows an empty array. 到目前为止,我已经能够生成所有链接(imageLinks)的数组,但是在最终控制台下面的代码中.log(linkedImages)始终显示一个空数组。

The thing I can't wrap my head around is where I've commented "This works / But this doesn't work:" 我不能说的就是我评论的内容:“这行得通/但是行不通:”

What am I doing wrong? 我究竟做错了什么? Any help is greatly appreciated for this somewhat noob. 非常感谢您对此有点菜鸟的任何帮助。 Thanks! 谢谢!

//Create an array of all the links containing img tags
var imageLinks = $("img").parent("a").map(function () {
    var h = $(this).attr("href");
    return h;
}).get();
//This correctly shows all the links:
//console.log(imageLinks);
//Declare an array to hold all the linked images 
var linkedImages = [];
//Loop through all the links to see if they're images or not
for (var l = 0; l < imageLinks.length; l++) {
    var currLink = imageLinks[l];

    function myCallback(url, answer) {
        if (answer) {
            //This works:
            console.log(url + ' is an image!');
            //But this doesn't work
            linkedImages.push(url);
        } else {
            //alert(url+' is NOT an image!');
        }
    }

    function IsValidImageUrl(url, callback) {
        var img = new Image();
        img.onerror = function () {
            callback(url, false);
        }
        img.onload = function () {
            callback(url, true);
        }
        img.src = url
    }
    IsValidImageUrl(currLink, myCallback);
};
//HELP! This always evaluates as just "[]"
console.log(linkedImages);

What @SLaks said. @SLaks说什么。 Since the loading of images is async, your callback doesn't fire until after the images have been loaded. 由于图像加载是异步的,因此只有在图像加载后才会触发回调。 To fix the problem, you can use $.Deferred from jQuery (I am assuming you are using jQuery since there is a $(...) in your code): 要解决此问题,您可以使用jQuery的$ .Deferred (我假设您使用的是jQuery,因为代码中有$(...)):

    function callback(dfd, url, answer) {
        if (answer) {
            //This works:
            console.log(url+' is an image!');
            //But this doesn't work
            dfd.resolve(url);
        } else {
            //alert(url+' is NOT an image!');
            dfd.reject();
        }
    }

    //Create an array of all the links containing img tags
    var imageLinks = $("img").parent("a").map(function() {
        var h = $(this).attr("href");
        return h;
    }).get();

    //This correctly shows all the links:
    //console.log(imageLinks);

    //Declare an array to hold all the linked images 
    var linkedImages = [];

    //Loop through all the links to see if they're images or not
    var dfds = [];
    for (var l=0; l<imageLinks.length; l++) {
        var currLink = imageLinks[l];
        var dfd = $.Deferred();
        dfd.done(function(url) { linkedImages.push(url); });
        dfds.push(dfd.promise());

        (function(dfd, url) {
            var img = new Image();
            img.onerror = function() { callback(dfd, url, false); }
            img.onload =  function() { callback(dfd, url, true); }
            img.src = url
        })(dfd, currLink);
    };

    $.when.apply(null, dfds).done(function() {
         console.log(linkedImages);
    });

Have not tested this, but the general idea for how to use deferred to reach your goal is in there. 还没有测试过,但是关于如何使用递延实现您的目标的一般想法就在那里。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM