Обработка зависимых обещаний: необработанное отклонение (ReferenceError) Не может получить доступ ко второму обещанию перед инициализацией

#javascript #promise #async-await

#javascript #обещание #асинхронное ожидание

Вопрос:

Я пытаюсь обрабатывать зависимые обещания с помощью axios в клиенте.

 const App=()=>{
     useEffect(()=>{
             onTermSubmit()
       },[])
 
     const onTermSubmit=async(term)=>{
       if (term) {
        const responseLongLat = await opencage.get(
                    `/geocode/v1/json/?q=${term}amp;key=myKey` 
                 //This makes a request to opencage API and return a object with 
                 // longitud and latitude
                        );
          
       console.log(responseLongLat.data.results[0].geometry);//{lat: 52.5170365, lng: 13.3888599}

        const responseWeather = await darksky.get(
            `/forecast/myKey/${responseLongLat.lat},${responseLongLat.lng}`
                // This makes a resquest to DarkSky API and return a object with 
                // weather data
           );
         console.log(responseWeather.data.daily);//{summary: "Rain on Thursday through next Saturday.", icon: "rain", data: Array(8)} if hardcoded lat, long; otherwise error

      };

        return (
               <div>
                   <SearchBar onFormSubmit={onTermSubmit} />
               </div>
          )
 }
  

Сначала я получил ошибку политики CORS, которую, как мне кажется, я преодолел, добавив https://cors-anywhere.herokuapp.com в главный домен DarkSky. И если я жестко закодирую широту и длину с конкретными данными (например, 52.5170365, 13.3888599), это сработает, и я получу свои данные о погоде за это время, широта.

Но если я помещу переменные в литеральную строку запроса в DarkSky, полученную из responseLongLat ($ {responseLongLat.lat},$ {responseLongLat.lng}) Я получил следующую ошибку: Необработанное отклонение (ReferenceError): не удается получить доступ к ‘responseWeather’ перед инициализацией

Комментарии:

1. В опубликованном вами коде вы никогда не обращаетесь responseWeather нигде.

2. Я консоль. запишите результаты обоих запросов для проверки. Я обновил код с помощью этой консоли. регистрирует и помещает их результаты

Ответ №1:

Вы можете использовать await только в асинхронной функции. Попробуйте это

 async function getWeatherData(term) {
 const responseLongLat = await opencage.get(
`/geocode/v1/json/?q=${term}amp;key=myKey` 
  //This makes a request to opencage API and return a object with 
  // longitud and latitude
  );

console.log(responseLongLat.data.results[0].geometry);//{lat: 52.5170365, lng: 
13.3888599}

const responseWeather = await darksky.get(
 '/forecast/myKey/52.5170365,13.3888599'
 // This makes a resquest to DarkSky API and return a object with 
 // weather data
);

console.log(responseWeather.data.daily);

}

if(term) {
    getWeatherData(term);
}
  

Комментарии:

1. Я ввел полную функцию с ключевым словом async. Функция находится внутри компонента в приложении React и должна принимать параметр: term. Параметр передается из другого компонента, который является формой, в которой пользователь вводит город (термин) и отправляет, передавая термин, представленный в качестве реквизита, основному компоненту, где находится вышеупомянутая функция. Итак, нам нужен этот параметр в функции.

2. Соответствующим образом обновил мой ответ.

3. Привет, спасибо, что следили за моим кодом. На самом деле я использую перехваты и, в частности, useEffect hook для извлечения API. Итак, prop, передающий ссылку на компонент SearchBar, ссылается onTermSubmit, но эта асинхронная функция находится в ловушке useEffect . Должен ли я передать термин основной функции в перехватчике?

4. Вы должны поместить функцию вне ловушки useEffect . Затем вызовите его из перехвата.

5. Да, это то, что я уже сделал, как указано в моем обновленном коде. Единственное, поскольку термин, поступающий из строки поиска, передается параметру в async func, условие должно быть в пределах этого.

Ответ №2:

Решением было, вместо того, чтобы передавать свойства возвращаемого объекта в первом вызове API прямо в буквальный шаблон второго вызова API, нам нужно сохранить их в двух отдельных переменных. Эти переменные мы передаем в шаблон literal.

  const responseLongLat = await opencage.get(
                `/geocode/v1/json/?q=${term}amp;key=myKey`)

 let responseWeatherLat = responseLongLat.data.results[0].geometry.lat;
 let responseWeatherLng = responseLongLat.data.results[0].geometry.lng;

 const responseWeather = await darksky.get(
 `/forecast/2623794cbf06a05c50f681a0869ab7ab/${responseWeatherLat},${responseWeatherLng}`
  );