Доступ к данным в функции обратного вызова

У меня есть функция геокодирования адреса, которая возвращает название города того же адреса

  // 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

Что вы имеете в виду под этим: "router.navigate не работает должным образом"?

Daniel W Strimpel 02.05.2018 16:09

он переходит по URL-адресу к списку, но представление шаблона не является шаблоном списка, он все еще добавляет шаблон формы. И я попытался вызвать другую функцию для открытия диалогового окна с ошибкой «this..confirmDialog (ErrorDialog,« Что-то не так »);». Он открывает диалоговое окно, но без сообщения, и если я вызываю эту функцию вне функции обратного вызова geocodeAddress, все работает правильно.

Ante Ereš 02.05.2018 16:12

Помимо обработки данных внутри обратного вызова geocodeAddress, измените function (results, status) { ... } на (results, status) => { ... }, чтобы сохранить значение this с помощью стрелочной функции.

ConnorsFan 02.05.2018 16:32
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
808
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы используете 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 не совсем понимает, как работает асинхронное программирование.

zero298 02.05.2018 16:26

это решение помогло мне. Спасибо

Ante Ereš 02.05.2018 16:30

Другие вопросы по теме