简体   繁体   中英

javascript onload event in a loop

I am trying to loop through an json array of images, adding the images to a marker on map. As javascript is asynchronous it is causing me problems, I want to wait for the image to load before adding it to my map and cannot get my images to load before the loop finishes. Is this possible to achieve as I have tried to implement with callbacks but could not get this to work.

 for (var i = 0; i < jsonObj.potholes.length; i++)
 {  
      var image = new Image();



                image.src = "data:image/png;base64," + jsonObj.potholes[i].image;
                image.onload = function()
                {
                    //alert("image loaded");
                    EXIF.getData(image, function()
                    {
                        otn = parseInt(EXIF.getTag(image, "Orientation"));
                        dataURL = drawCanvas(otn, image).toDataURL();

                        var circle = L.circle([jsonObj.potholes[i].lat, jsonObj.potholes[i].lon], 18, {
                            color: 'yellow',
                            fillColor: 'red',
                            fillOpacity: 0.5
                        }).addTo(markersLayerGroup).bindPopup("Pothole ID " + jsonObj.potholes[i].id
                                + "<br />Location " + city[i] + "," + street[i] +
                                "<image src = '" + dataURL + "'></image>");


                    });



}

You should implement an asynchronous loop (using if ):

(function (ondone) {
    var index = 0;
    nextStep();

    function nextStep() {
        if (index >= jsonObj.potholes.length) {
            if (ondone)
                ondone();
            return;
        }

        var i = index++;
        var image = new Image();

        image.src = "data:image/png;base64," + jsonObj.potholes[i].image;
        image.onload = function () {
            //alert("image loaded");
            EXIF.getData(image, function () {
                otn = parseInt(EXIF.getTag(image, "Orientation"));
                dataURL = drawCanvas(otn, image).toDataURL();

                var circle = L.circle([jsonObj.potholes[i].lat, jsonObj.potholes[i].lon], 18, {
                    color: 'yellow',
                    fillColor: 'red',
                    fillOpacity: 0.5
                }).addTo(markersLayerGroup).bindPopup("Pothole ID " + jsonObj.potholes[i].id
                        + "<br />Location " + city[i] + "," + street[i] +
                        "<image src = '" + dataURL + "'></image>");

                nextStep();
            });
        }
    }
})(function () { alert("Done!"); });

You could also use Promises for that, for example: JavaScript: Async Promise "while loop" .

Hope it's not too late. There's another much simpler solution--Throw everything into another function.

for (var i = 0; i < jsonObj.potholes.length; i++) {  
    dataOnLoad("data:image/png;base64," + jsonObj.potholes[i].image);
}
function dataOnLoad(base64_data) {
    var image = new Image();
    image.src = base64_data;
    image.onload = function()
    {
        //alert("image loaded");
        EXIF.getData(image, function()
        {
            otn = parseInt(EXIF.getTag(image, "Orientation"));
            dataURL = drawCanvas(otn, image).toDataURL();

            var circle = L.circle([jsonObj.potholes[i].lat, jsonObj.potholes[i].lon], 18, {
                color: 'yellow',
                fillColor: 'red',
                fillOpacity: 0.5
            }).addTo(markersLayerGroup).bindPopup("Pothole ID " + jsonObj.potholes[i].id
                    + "<br />Location " + city[i] + "," + street[i] +
                    "<image src = '" + dataURL + "'></image>");


        });
}

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