首页 > 解决方案 > 与 streetViewService 异步 - 回调使用失败

问题描述

我编写了一个 JS 脚本来接收给定点(纬度、经度)的最近街景位置。我对(在我看来)回调函数有问题。

这是代码:

<html>
  <head>
    <meta charset="utf-8">
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  </head>
  <body>
      <input type="file" id="file-input" />
      <h3>Contents of the file:</h3>
      <pre id="file-content"></pre>
    <div class="container">
      <div>gid,lat_from,lon_from</div>>
    </div>

    <script>

function readSingleFile(e) {
  var file = e.target.files[0];
  if (!file) {
    return;
  }
  var reader = new FileReader();
  reader.onload = function(e) {
    var contents = e.target.result;
    processFile(contents, returnFile)
    
  };

  reader.readAsText(file);
}

result = "";


function processFile(contents, callback) {
  var text = contents
  var splitted = text.split('\r\n')

  splitted.forEach(function(point) {
    var gid = point.split(';')[0]
    var latilong = point.split(';')[1].replace(/[\ ]/g, '')
    var splitted2 = latilong.split(':')

    var lat = splitted2[1].split(',')[0]
    var lon = splitted2[2].split('}')[0]
    var latilong = new google.maps.LatLng(lat, lon);

    // alert(latilong)

    var radius = 20
    var streetViewService = new google.maps.StreetViewService();
    streetViewService.getPanoramaByLocation(latilong, radius, function(data, status)
      {
        if (status == google.maps.StreetViewStatus.OK)
        {
          var nearStreetViewLocation = data.location.latLng;
         
          result = result + gid + ', ' + JSON.stringify(nearStreetViewLocation).replace(/[\" \} \{ lat long \:]/g,'') + '</br>';
          $( ".container" ).append(result);
          $( ".container" ).append('<br/>');
        }
        else {
          $( ".container" ).append("<div> "+ gid + ', 0' + "</div>" );      
        }
          
        });
    });

  if (callback) {
      callback(result);
  }
}

function returnFile(results) {
  if(results) {
  	$( ".container" ).append('<br/> from callback function: </br>');
  	$( ".container" ).append(results);
  } else {
  	alert('results is null');
  }
}


document.getElementById('file-input')
  .addEventListener('change', readSingleFile, false);
      
       </script>
  </body>
</html>

例如,您可以使用给定的文本文件运行脚本:

7512 ; {lat:52.2254802729, lon:21.0105694375}
7513 ; {lat:52.2254556313, lon:21.0104179005}
7563 ; {lat:52.2245593608, lon:21.0063570311}

如您所见, returnFile函数中的results变量为空(警告results为空)。在processFile函数中不为空(递增内容显示在".container"中),并在processFile函数中传递给returnFile函数。

如何修复?我认为这样的回调足以从processFile函数传递一个非空变量。

我想在将它填充到processFile之后在returnFile函数中处理结果变量。

干杯!

标签: javascriptgoogle-api

解决方案


好像我通过在 forEach 中使用计数器解决了这个问题(如那里所说:Callback after all asynchronous forEach callbacks are completed),这是代码:

<html>
  <head>
    <meta charset="utf-8">
    <title>Directly accessing Street View data</title>
    <style>
      html, body, #map-canvas {
        height: 100%;
        margin: 0px;
        padding: 0px
      }
    </style>
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  </head>
  <body>
      <input type="file" id="file-input" />
      <h3>Contents of the file:</h3>
      <pre id="file-content"></pre>
    <div class="container">
      <div>gid,lat_from,lon_from</div>>
    </div>

    <script>

function readSingleFile(e) {
  var file = e.target.files[0];
  if (!file) {
    return;
  }
  var reader = new FileReader();
  reader.onload = function(e) {
    var contents = e.target.result;
    processFile(contents, returnFile)
    
  };

  reader.readAsText(file);
}

result = "";


function processFile(contents, callback) {
  var text = contents
  var splitted = text.split('\r\n')
  $( ".container" ).append("splitted length: " + splitted.length + "<br>");
  var itemsProcessed = 0;

  splitted.forEach(function(point) {
    var gid = point.split(';')[0]
    var latilong = point.split(';')[1].replace(/[\ ]/g, '')
    var splitted2 = latilong.split(':')

    var lat = splitted2[1].split(',')[0]
    var lon = splitted2[2].split('}')[0]
    var latilong = new google.maps.LatLng(lat, lon);

    // alert(latilong)

    var radius = 20
    var streetViewService = new google.maps.StreetViewService();
    streetViewService.getPanoramaByLocation(latilong, radius, function(data, status)
      {
        itemsProcessed++;
        if (status == google.maps.StreetViewStatus.OK)
        {
          var nearStreetViewLocation = data.location.latLng;
          // alert(nearStreetViewLocation)
          // $( ".container" ).append("<div> "+ gid + ', ' + JSON.stringify(nearStreetViewLocation).replace(/[\" \} \{ lat long \:]/g,'') +"</div>" );  
          // console.log(gid + ', ' + JSON.stringify(nearStreetViewLocation).replace(/[\" \} \{ lat long \:]/g,''))          
          result = result + gid + ', ' + JSON.stringify(nearStreetViewLocation).replace(/[\" \} \{ lat long \:]/g,'') + '<br>';
          $( ".container" ).append(result);
          $( ".container" ).append('<br/>');
          $( ".container" ).append("items processed: " + itemsProcessed);
          if(itemsProcessed === splitted.length) {
            callback(result);
          }
        }
        else {
          $( ".container" ).append("<div> "+ gid + ', 0' + "</div>" );      
        }
          
      });
    });

  // if (callback) {
  //     callback(result);
  // }
}

function returnFile(results) {
  if(results) {
    alert('results is not null');
  	$( ".container" ).append('<br/> from callback function: </br>');
  	$( ".container" ).append(results);
  } else {
  	alert('results is null');
  }
}


document.getElementById('file-input')
  .addEventListener('change', readSingleFile, false);

      //  points5 = [{lat:52.2254802729, lng:21.0105694375},
      // {lat:52.2254556313, lng:21.0104179005},
      // {lat:52.2245593608, lng:21.0063570311},
      // {lat:52.2245355399, lng:21.0062524214},
      // {lat:52.2245125335, lng:21.0061437961}];
      
      // // points5.forEach(function(point) {
      // //   $( ".container" ).append("<div>"+ JSON.stringify(point, null).replace(/\"/g,'') +"</div>" );
      // // });
      // var radius = 20
      // var streetViewService = new google.maps.StreetViewService();
      // points5.forEach(function(point) {
      //   streetViewService.getPanoramaByLocation(point, radius, function(data, status)
      //   {
      //       if (status == google.maps.StreetViewStatus.OK)
      //       {
      //         var nearStreetViewLocation = data.location.latLng;
      //         alert(nearStreetViewLocation)
      //         $( ".container" ).append("<div>"+ JSON.stringify(nearStreetViewLocation).replace(/[\" \} \{ lat long \:]/g,'') +"</div>" );            
      //         return nearStreetViewLocation
      //       }
      //       else {
      //         alert("error")
      //       }
      //   });
      // });
      
      
       </script>
  </body>
</html>


推荐阅读