简体   繁体   中英

JavaScript variables undefined within setTimeout function

I have the following code:

    for (var i = 0; i < markers.length; i++) {

        var lat = markers[i][0];
        var lng = markers[i][1];
        var img = markers[i][2];
        var info = markers[i][3];

        setTimeout(function(lat, lng, img, info) {
            console.log(lat + ', ' + lng);
            $('#map').gmap3({
                action: 'addMarker',
                latLng:[lat, lng],
                options:{
                    animation: google.maps.Animation.DROP,
                    icon: img
                },
                events:{
                    click: function(marker, event, data){
                        $(this).gmap3({action:'addinfowindow', anchor:marker, options:{content: '<div id="content" style="width:300px;height:250px;"><img src="' + info + '"></img></div>'}});
                        /*var infowindow = $(this).gmap3({action:'get', name:'infowindow'});
                        infowindow.close();*/
                    },
                }
            });
        }, i* 100);
    }

The console.log is showing undefined for lat and lng. Why is this?

Previously I didn't pass any variables into the function within timeout and they WERE defined but it used the same one for each marker in the for loop which was obviously wrong!

Any ideas?

lat and lng are named parameters of your timeout function, but setTimeout does not pass any parameters to that function, so they remain undefined.

You should move the timeout setup into a separate function, in order to establish a closure for your variables:

function configureTimeout(i, lat, lng, img, info) {
    setTimeout(function() {
        console.log(lat + ', ' + lng);
        $('#map').gmap3({
            action: 'addMarker',
            latLng:[lat, lng],
            options:{
                animation: google.maps.Animation.DROP,
                icon: img
            },
            events:{
                click: function(marker, event, data){
                    $(this).gmap3({action:'addinfowindow', anchor:marker, options:{content: '<div id="content" style="width:300px;height:250px;"><img src="' + info + '"></img></div>'}});
                    /*var infowindow = $(this).gmap3({action:'get', name:'infowindow'});
                    infowindow.close();*/
                },
            }
        });
    }, i* 100);
}

for (var i = 0; i < markers.length; i++) {

    var lat = markers[i][0];
    var lng = markers[i][1];
    var img = markers[i][2];
    var info = markers[i][3];

    configureTimeout(i, lat, lng, img, info);

}

try this:

setTimeout(function(){myFunc(lat, lng, img, info);},i*100)

function myFunc(lat, lng, img, info) { .... }

You need to pass those parameters to the anonymous function, setTimeout will not do it for you:

setTimeout(function () { 
    (function(lat, lng, img, info) {
        console.log(lat + ', ' + lng);
        // ... snip ...
    })(lat, lng, img, info);
}, i* 100);

setTimeout(function(lat, lng, img, info) {

应该

setTimeout(function() {

You need to enclose your setTimeout in a closure, self-executing with the current params values:

for (var i = 0; i < markers.length; i++) {

    var lat = markers[i][0];
    var lng = markers[i][1];
    var img = markers[i][2];
    var info = markers[i][3];
    (function(latitude, longitude, image, infos) { // Attention these must be named differently!
        setTimeout(function() {
            console.log(latitutde + ', ' + longitude); // use the inner param names here and after!
            $('#map').gmap3({ ...omitted... }});
        }, i* 100);
    })(lat, lng, img, info)
}

By the way, there is not much difference with @lanzz solution above, which I think is even better since it refactors out the actual function, which is a lot cleaner! :)

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