我写了一个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 函数中处理 result 变量。
干杯!
答案 0 :(得分:0)
好像我通过在forEach中使用counter来解决了这个问题(如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>