#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}`
);