У меня есть функция геокодирования адреса, которая возвращает название города того же адреса
// geocode the given address
geocodeAddress(address, callback) {
this.mapsAPILoader.load().then(() => {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
results[0].address_components.forEach(arrAddress => {
if (arrAddress.types[0] == "locality") {
callback(arrAddress.long_name);
}
})
} else {
console.info("Geocode was not successful for the following reason: " + status);
}
});
});
};
когда я вызываю эту функцию и хочу напечатать название города, она печатается как undefined из строки кода под функцией geocodeAddress, а после этого печатается правильно название города
this.geocodeAddress(this.offerAddress, data => {
this.hostCity = data;
console.info(this.hostCity);
});
console.info(this.hostCity);
Я пытался добавить тайм-аут перед второй функцией console.info, но безуспешно
поэтому меня интересует, как получить доступ к этому значению после возврата данных из геокодера, потому что мне нужно использовать эти данные для хранения в базе данных, и если я попытаюсь сохранить как это
this.geocodeAddress(this.offerAddress, data => {
this.hostCity = data;
this.service.addData({"address": this.offerAddress, "city": this.hostCity}, "/data")
.subscribe(data => {
this.router.navigate(['list']);
})
});
он хранит данные, но router.navigate не работает должным образом
поэтому мне нужно решение для доступа к hostCity вне функции обратного вызова geocodeAddress или как правильно вызвать какую-либо другую функцию внутри этой функции обратного вызова geocodeAddress
он переходит по URL-адресу к списку, но представление шаблона не является шаблоном списка, он все еще добавляет шаблон формы. И я попытался вызвать другую функцию для открытия диалогового окна с ошибкой «this..confirmDialog (ErrorDialog,« Что-то не так »);». Он открывает диалоговое окно, но без сообщения, и если я вызываю эту функцию вне функции обратного вызова geocodeAddress, все работает правильно.
Помимо обработки данных внутри обратного вызова geocodeAddress, измените function (results, status) { ... } на (results, status) => { ... }, чтобы сохранить значение this с помощью стрелочной функции.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Если вы используете TypeScript, вы можете заставить ваш метод geocodeAddress возвращать Promise вместо использования обратных вызовов, а затем использовать async/await:
async geocodeAddress(address): Promise<string[]> {
return new Promise((resolve, reject) => {
this.mapsAPILoader.load().then(() => {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
const result: string[] = [];
results[0].address_components.forEach(arrAddress => {
if (arrAddress.types[0] == "locality") {
result.push(arrAddress.long_name);
}
});
resolve(results);
} else {
console.info("Geocode was not successful for the following reason: " + status);
reject(status);
}
});
});
});
};
Теперь эта функция возвращает массив с длинными именами всех адресов, которые вы искали. Чтобы использовать это:
const data: string[] = await this.geocodeAddress(this.offerAddress);
this.hostCity = data[0];
// do whatever you want now
Таким образом, вы получаете преимущества асинхронного программирования с простотой синхронного.
Зачем отвечать на этот вопрос вместо того, чтобы направлять OP на канонический вопрос об асинхронной ссылке? Не имеет значения, использует OP машинописный текст или нет. Важно то, что OP не совсем понимает, как работает асинхронное программирование.
это решение помогло мне. Спасибо
Что вы имеете в виду под этим: "router.navigate не работает должным образом"?