来自 [Mark Meyer][1] 回复:
您的主要问题是geocoder.geocode() 是异步的并且需要回调。您将一个函数传递给回调,但将返回值视为将从主函数findLatLang() 返回,但它不会。目前findLatLang() 不返回任何内容。
findLatLang() 是你应该拥有承诺并从函数中返回的地方:
function findLatLang(address, geocoder, mainMap) {
return new Promise(function(resolve, reject) {
geocoder.geocode({'location': address}, function(results, status) {
if (status === 'OK') {
console.log(results);
resolve([results[0].geometry.location.lat(), results[0].geometry.location.lng()]);
} else {
reject(new Error('Couldnt\'t find the location ' + address));
}
})
})
}
然后在getPoints() 的循环中,您可以将这些promise 收集到一个数组中,并在数组上调用Promise.all(),一旦所有promise 都解决了,它将为您提供值:
function getPoints(geocoder,map) {
let locationData = [];
var indirizzo = [];
for (var i = 0; i < savedRepods.length; i++) {
for (var a = 0; a < ids.length; a++) {
if(savedRepods[i] == ids[a]) {
var geocoder = new google.maps.Geocoder;
var latlngStr = coords[a].split(',', 2);
var latlng = {lat: parseFloat(latlngStr[0]), lng: parseFloat(latlngStr[1])};
locationData.push(findLatLang(latlng, geocoder, map))
console.log(indirizzo[a]);
}
}
}
return locationData // array of promises
}
var locations = getPoints(geocoder,map)
Promise.all(locations)
.then(function(returnVals){
// you should have return values here when
// all promises have rsolved
console.log(returnVals);
})
Promise.all() 方法返回一个 Promise,当所有作为 iterable 传递的 Promise 都已完成时,或者当 iterable 不包含 Promise 时,或者当 iterable 包含已完成的 Promise 和已完成的非 Promise 时,该 Promise 完成返回。
尚不清楚addressData 的来源——您在函数中使用它,但它没有被传递到任何地方。
查看 [Mark Meyer][1] 的概念证明 回复:
proof of concept fiddle
代码 sn-p:
(function($) {
var savedRepods = <?php echo json_encode($userPostsInternal); ?>;
savedRepods = savedRepods.split(",");
var date = [],
coords = [],
ids = [],
metal = [],
plastic = [],
paper = [],
glass = [],
indirizzo = [];
var array = <?php echo $contents; ?>;
array.map(function(item) {
coords.push(item.Lat + "," + item.Lng);
ids.push(item.ID);
date.push(item.Date);
plastic.push(item.Plastic);
paper.push(item.Paper);
glass.push(item.Glass);
metal.push(item.Metal);
});
/**
* findLatLang
*/
function findLatLang(location, geocoder, value) {
/**
* Return new Promise what resolves when
* the geocoder is successfull
* and push in the array of promises
*/
return new Promise(function(resolve, reject) {
/** Do geocoder */
geocoder.geocode({
'location': location
}, function(results, status) {
/**
* If geocoder is Ok
*/
if (status === 'OK') {
/**
* When the geocoder is successfull located
* resolve the promise and send the response of formate address
*/
resolve([results[0].formatted_address, value]);
} else {
/**
* Reject the promise
*/
reject(new Error('Couldnt\'t find the location ' + location));
}
})
})
}
/**
* processData
* return an array of promises
*/
function getPoints() {
/**
* Declare a variable of promises that have a geocoder
*/
let locationData = [];
for (var i = 0; i < savedRepods.length; i++) {
for (var a = 0; a < ids.length; a++) {
if (savedRepods[i] == ids[a]) {
var geocoder = new google.maps.Geocoder;
var latlngStr = coords[a].split(',', 2);
var latlng = {
lat: parseFloat(latlngStr[0]),
lng: parseFloat(latlngStr[1])
};
/**
* Push geocoder in array of locationdata
* Send the geocoder object on function and send the map
*/
locationData.push(findLatLang(latlng, geocoder, a))
}
}
}
/** return array of promises */
return locationData;
}
/**
* Now process the response from locationData
*/
var locations = getPoints();
/**
* Promise all
* freecodecamp.org/news/…
* The Promise.all() method returns a single Promise that fulfills when all of the promises
* passed as an iterable have been fulfilled or when the iterable contains no promises or when
* the iterable contains promises that have been fulfilled and non-promises that have been returned.
* It rejects with the reason of the first promise that rejects, or with the error caught by the
* first argument if that argument has caught an error inside it using try/catch/throw blocks.
* ONLY RETURN VALUE WHEN ALL PROMISES HAS ENDED
* @TODO => SHOW LOADER IN PROCESS
*/
Promise.all(locations)
.then(function(returnVals) {
console.warn(returnVals)
_indirizzo = returnVals;
doAddress(_indirizzo)
});
function doAddress(_indirizzo) {
_indirizzo.forEach(function(item) {
var a = item[1];
var location = item[0];
$("#eachValue ul").append("<li class='list-group-item'>repod id= " + ids[a] + "<br> Indirizzo = " + location + "<br> Metallo = " + metal[a] + ", <br> Plastica = " + plastic[a] + ", <br> Vetro = " + glass[a] + ", <br> Carta = " + paper[a] + "</li>");
})
}
})(jQuery);