如何从 Google Places 获取一系列地点的坐标,然后在完成所有操作后使用结果?
How can I get coordinates from Google Places for an array of places and then use the results after all are done?
我有一组地名,例如:
const places = ['King Square, London', 'Empire State Building', 'Great Wall of China'];
我需要一个新的对象数组,其中为地名数组中的每个元素设置了位置,例如:
const places = [
{ name: 'King Square, London', position: { latitude: ..., longitude: ... } },
...
];
我想我必须做这样的事情:
const places = [];
['King Square, London', 'Empire State Building', 'Great Wall of China'].forEach(placeName => {
axios
.get(`https://maps.googleapis.com/maps/api/place/textsearch/json?key=GOOGLE_PLACES_API_KEY&query=${placeName}`)
.then(response => {
if (!!response && !!response.results && !!response.results[0]) {
const searchResult = response.results[0];
if (!!searchResult) {
axios
.get(`https://maps.googleapis.com/maps/api/place/details/json?key=GOOGLE_PLACES_API_KEY&placeid=${searchResult.place_id}`)
.then(response => {
const placeResult = response.result;
if (!!placeResult) {
places.push({ name: placeName, position: placeResult.geometry.location })
但是好像不行。
它应该是什么样子才能填充 places
并在填充后使用数组?在使用它之前,我是否必须使用 Promises 来确保它已被填充?
更新现有代码的步骤:
- 使用 Array.map() instead of forEach() 将承诺存储在数组中。
- 回调到 map() return 承诺(即
axios.get().then()
的 return 值)。
- 调用 axios.get() 的响应将有一个包含结果的 data 属性,因此请使用
response.data.results
而不是 response.results
- Return再次承诺
然后在设置了 promises 数组后,可以使用 Promise.all():
const places = [];
//1 - store promises in an array
var promises = ['King Square, London', 'Empire State Building', 'Great Wall of China'].map(placeName => {
return axios //2 - return promise
.get(`https://maps.googleapis.com/maps/api/place/textsearch/json?key=GOOGLE_PLACES_API_KEY&query=${placeName}`)
.then(response => {
//3 - use response.data.results instead of response.results
if (!!response && !!response.data && !!response.data.results && !!response.data.results[0]) {
const searchResult = response.data.results[0];
if (!!searchResult) {
return axios //4 return nested promise
.get(`https://maps.googleapis.com/maps/api/place/details/json?key=GOOGLE_PLACES_API_KEY&placeid=${searchResult.place_id}`)
.then(response => {
const placeResult = response.data.result;
if (!!placeResult) {
places.push({ name: placeName, position: placeResult.geometry.location });
}
})
}
}
});
});
//5 - After promises are done, use the places array
Promise.all(promises).then(results => {
console.log('places:', places);
})
输出:
places: [ { name: 'King Square, London',
position: { lat: 51.52757920000001, lng: -0.0980441 } },
{ name: 'Great Wall of China',
position: { lat: 40.4319077, lng: 116.5703749 } },
{ name: 'Empire State Building',
position: { lat: 40.7484405, lng: -73.98566439999999 } } ]
客户端示例Javascript
下面是(客户端)JavaScript 的端口。请注意它非常相似,但使用 Whosebug API(因为那样不会有 CORS 问题)。
var ranks = [];
var promises = [94, 95].map(badgeId => {
return axios.get(`https://api.stackexchange.com/2.2/badges/${badgeId}?site=Whosebug&order=desc&sort=rank&filter=default`)
.then(response => {
var responsebadgeId = response.data.items[0].badge_id;
return axios.get(`https://api.stackexchange.com/2.2/badges/${responsebadgeId}/recipients?site=Whosebug`)
.then(response => {
console.log('pushing rank into array from data: ',response.data.items[0].rank);
ranks.push(response.data.items[0].rank);
});
});
});
Promise.all(promises).then(responses => {
console.log('promises all callback - ranks:',ranks);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.2/axios.min.js"></script>
我有一组地名,例如:
const places = ['King Square, London', 'Empire State Building', 'Great Wall of China'];
我需要一个新的对象数组,其中为地名数组中的每个元素设置了位置,例如:
const places = [
{ name: 'King Square, London', position: { latitude: ..., longitude: ... } },
...
];
我想我必须做这样的事情:
const places = [];
['King Square, London', 'Empire State Building', 'Great Wall of China'].forEach(placeName => {
axios
.get(`https://maps.googleapis.com/maps/api/place/textsearch/json?key=GOOGLE_PLACES_API_KEY&query=${placeName}`)
.then(response => {
if (!!response && !!response.results && !!response.results[0]) {
const searchResult = response.results[0];
if (!!searchResult) {
axios
.get(`https://maps.googleapis.com/maps/api/place/details/json?key=GOOGLE_PLACES_API_KEY&placeid=${searchResult.place_id}`)
.then(response => {
const placeResult = response.result;
if (!!placeResult) {
places.push({ name: placeName, position: placeResult.geometry.location })
但是好像不行。
它应该是什么样子才能填充 places
并在填充后使用数组?在使用它之前,我是否必须使用 Promises 来确保它已被填充?
更新现有代码的步骤:
- 使用 Array.map() instead of forEach() 将承诺存储在数组中。
- 回调到 map() return 承诺(即
axios.get().then()
的 return 值)。 - 调用 axios.get() 的响应将有一个包含结果的 data 属性,因此请使用
response.data.results
而不是response.results
- Return再次承诺
然后在设置了 promises 数组后,可以使用 Promise.all():
const places = []; //1 - store promises in an array var promises = ['King Square, London', 'Empire State Building', 'Great Wall of China'].map(placeName => { return axios //2 - return promise .get(`https://maps.googleapis.com/maps/api/place/textsearch/json?key=GOOGLE_PLACES_API_KEY&query=${placeName}`) .then(response => { //3 - use response.data.results instead of response.results if (!!response && !!response.data && !!response.data.results && !!response.data.results[0]) { const searchResult = response.data.results[0]; if (!!searchResult) { return axios //4 return nested promise .get(`https://maps.googleapis.com/maps/api/place/details/json?key=GOOGLE_PLACES_API_KEY&placeid=${searchResult.place_id}`) .then(response => { const placeResult = response.data.result; if (!!placeResult) { places.push({ name: placeName, position: placeResult.geometry.location }); } }) } } }); }); //5 - After promises are done, use the places array Promise.all(promises).then(results => { console.log('places:', places); })
输出:
places: [ { name: 'King Square, London',
position: { lat: 51.52757920000001, lng: -0.0980441 } },
{ name: 'Great Wall of China',
position: { lat: 40.4319077, lng: 116.5703749 } },
{ name: 'Empire State Building',
position: { lat: 40.7484405, lng: -73.98566439999999 } } ]
客户端示例Javascript
下面是(客户端)JavaScript 的端口。请注意它非常相似,但使用 Whosebug API(因为那样不会有 CORS 问题)。
var ranks = [];
var promises = [94, 95].map(badgeId => {
return axios.get(`https://api.stackexchange.com/2.2/badges/${badgeId}?site=Whosebug&order=desc&sort=rank&filter=default`)
.then(response => {
var responsebadgeId = response.data.items[0].badge_id;
return axios.get(`https://api.stackexchange.com/2.2/badges/${responsebadgeId}/recipients?site=Whosebug`)
.then(response => {
console.log('pushing rank into array from data: ',response.data.items[0].rank);
ranks.push(response.data.items[0].rank);
});
});
});
Promise.all(promises).then(responses => {
console.log('promises all callback - ranks:',ranks);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.2/axios.min.js"></script>