简体   繁体   中英

Pushing to an Array within a jQuery each loop

I'm using jQuery to parse an XML file, and I'm trying to push each element in the XML file to an array using a jQuery .each loop. Strangely, if I alert the value of the array within the loop it comes out as it should, but if I try to alert a value in the array after the loop has finished it results in "undefined".

Is there something strange that happens when you push values to an array within this kind of a loop?


Here is the Javascript:

var splashArray = new Array();

// Load the Splash XML file and assign each image within to an array
$.get('splash.xml', function(xml) {
    $('image', xml).each(function (i) {
        splashArray.push($(this).attr("src"));
    });
});

alert(splashArray[1]); // Results in undefined



Here is the XML:

<?xml version="1.0" encoding="UTF-8"?>
<site>      
    <image src="splash1.jpg" />
    <image src="splash2.jpg" />
    <image src="splash3.jpg" />
    <image src="splash4.jpg" />
    <image src="splash5.jpg" />
    <image src="splash6.png" />
</site>

Correct variant:

var splashArray = new Array();

// Load the Splash XML file and assign each image within to an array
$.get('splash.xml', function(xml) {
        $('image', xml).each(function (i) {
                splashArray.push($(this).attr("src"));
        });
        alert(splashArray[1]);
});

In your variant of code alert(splashArray[1]); executes before ajax get xml result, therefore splashArray was empty, when you try to alert element with index 1. Your code works well only for synchronous mode, when thread waits for server response. In Asynchronous mode you should use callback function.

Variant with callback:

var splashArray = new Array();

// Load the Splash XML file and assign each image within to an array
$.get('splash.xml', function(xml) {
        $('image', xml).each(function (i) {
                splashArray.push($(this).attr("src"));
        });
        work_with_splash();
});

function work_with_splash () {
    alert(splashArray[1]);
}

Or one more pattern (pseudocode):

function process(ajax_is_done) {
    if (!ajax_is_done) {
        ajax(function (result) {
            import_result(result);
            process(true);
        })
    }
}
process();

You are alerting before the array is being populated. You need to understand that XHR/Ajax is asynchronous ( as opposed to synchronous ) so the alert will not always run after the callback function because it will take a few seconds to do the actual HTTP request to grab the xml, alerting inside the callback ensures that it is populated after the XHR stuff is done.

Works:

var splashArray = [];

function fn() {
    alert(splashArray[1]);
}

$.get('splash.xml', function(xml) {
        $('image', xml).each(function (i) {
                splashArray.push($(this).attr("src"));
        });
        fn();
});

Doesn't work:

var splashArray = [];

$.get('splash.xml', function(xml) {
        $('image', xml).each(function (i) {
                splashArray.push($(this).attr("src"));
        });
        // this will populate the array almost always AFTER the alert below.
});


alert(splashArray[1]); // this will almost ALWAYS alert BEFORE the callback function is done

如果您不想使用标准回调,则另一个选项是触发jQuery事件。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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