Как выполнить несколько асинхронных функций в зависимости друг от друга? - PullRequest
0 голосов
/ 10 сентября 2018

кажется, я понимаю поведение async / await, но сейчас-сейчас я глубоко застрял в своей проблеме и не могу ее решить.Я пытаюсь создать приложение погоды, поэтому мне нужно сначала запросить широту и долготу, а затем получить эту информацию, чтобы отправить запрос в API погоды и получить прогноз.Как сказано в документации Google

Доступ к сервису геокодирования является асинхронным, поскольку API Карт Google необходимо совершить вызов на внешний сервер.

Поэтому я пытаюсь использовать async / await для обработки.

import Search from './models/Search';
import * as searchView from './views/searchView';
import { elements } from './views/base';

/*
* Search controller
*/

const state = {

};

const controlSearch = async () => {
  const query = searchView.getInput();

  if (query) {
    state.forecast = new Search(query);

    try {
      await state.forecast.codeAddress();
      await state.forecast.getForecast(state.forecast);
      console.log(state);
    } catch (error) {
      console.log(error);
    }
  }
};

elements.searchForm.addEventListener('submit', (e) => {
  e.preventDefault();
  controlSearch();
});

это мой контроллер.Внизу я поместил eventListener в форму, которую пользователь будет использовать для поиска города и получения прогноза.

Это моя модель поиска

import { key, proxy } from '../config';

export default class Search {
  constructor(query) {
    this.query = query;
  }

  codeAddress() {
    const geocoder = new google.maps.Geocoder();
    geocoder.geocode({ address: this.query }, (results, status) => {
      if (status === 'OK') {
        this.latitude = results[0].geometry.location.lat();
        this.longitude = results[0].geometry.location.lng();
        console.log(this.latitude, this.longitude, 'lat long');
      }
    });
  }

  async getForecast(geometry) {
    console.log(geometry, 'geometry');
    const result = await fetch(`${proxy}https://api.darksky.net/forecast/${key}/${geometry.latitude},${geometry.longitude}`);
    const forecast = await result.json();
    forecast.then((res) => {
      this.forecast = res;
    });
  }
} 

Проблема в том, что когдапри запросе к API darkSky geometry.latitude и geometry долгота не определены.

Как мне справиться с этой проблемой?

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

codeAddress является асинхронным (поскольку ответ обрабатывается в обратном вызове), но вы не рассматриваете его как асинхронный.Попробуйте это:

async codeAddress() {
  const geocoder = new google.maps.Geocoder();
  return new Promise((resolve, reject) => {
    geocoder.geocode({ address: this.query }, (results, status) => {
      if (status === 'OK') {
        this.latitude = results[0].geometry.location.lat();
        this.longitude = results[0].geometry.location.lng();
        console.log(this.latitude, this.longitude, 'lat long');
        resolve();
      } else {
        reject();
      }
    });
  });
}

Существуют и другие способы преобразования функции с обратным вызовом в асинхронный.

0 голосов
/ 10 сентября 2018

codeAddress не await ничего или возвращает что-то, что await ред. Он закрывается немедленно, даже если geocode еще не завершен. Пусть он вернет Promise, который может быть await ред.

codeAddress() {
  return new Promise((resolve, reject) => {
    const geocoder = new google.maps.Geocoder();
    geocoder.geocode({
      address: this.query
    }, (results, status) => {
      if (status === 'OK') {
        this.latitude = results[0].geometry.location.lat();
        this.longitude = results[0].geometry.location.lng();
        console.log(this.latitude, this.longitude, 'lat long');
        resolve();
      } else {
        reject();
      }
    });
  });
}

К сожалению, вам нужно будет вручную вернуть Promise, так как Geocoder.geocode() API следует только асинхронизации в стиле обратного вызова, а await будет ожидать только на .then() -блоки (например, * * тысяча двадцать-одина). * * тысяча двадцать две

...