【问题标题】:javascript onload event in a loop循环中的javascript onload事件
【发布时间】:2014-02-16 11:56:51
【问题描述】:

我正在尝试遍历图像的 json 数组,将图像添加到地图上的标记中。由于 javascript 是异步的,它给我带来了问题,我想在将图像添加到我的地图之前等待图像加载,并且在循环完成之前无法加载我的图像。这是否可以实现,因为我尝试使用回调实现但无法使其工作。

 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>");


                    });



}

【问题讨论】:

    标签: javascript jquery loops asynchronous onload


    【解决方案1】:

    你应该实现一个异步循环(使用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!"); });
    

    您也可以为此使用 Promises,例如:JavaScript: Async Promise "while loop"

    【讨论】:

      【解决方案2】:

      希望还为时不晚。还有一个更简单的解决方案——把所有东西都扔到另一个函数中。

      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>");
      
      
              });
      }
      

      【讨论】:

      • 这确实让我发笑。 4年后:“希望还为时不晚”。整洁的解决方案 - 对我有用且简单!