Я пишу бота discord.js и пытаюсь вызвать погодный API с помощью Node.js / snekfetch. Проблема в том, что я не могу понять, как просто поместить данные, возвращаемые из API, в объект javascript. Я хочу сделать что-то вроде этого:
let [country, ...city] = args;
let url = `http://api.openweathermap.org/data/2.5/forecast?q=${city},${country}&units=metric&APPID=${config.weatherID};`;
var weatherObject;
snekfetch.get(url).then(r => weatherObject = r.body);`
но, очевидно, это не работает, так что я делаю не так? Кажется, это должно быть безумно просто, но я просто не могу этого сделать. Ничего из того, что я искал в Google, не помогло, так как snkfetch, похоже, не получил широкого распространения, и я был совершенно неспособен экстраполировать что-либо, что я узнал о обещаниях, на этот сценарий.
Обновлено: уточнить:
snekfetch.get(url).then(r => console.info(r.body));
выводит объект на консоль точно так, как ожидалось, в то время как
snekfetch.get(url).then(r => weatherObject = r.body);
console.info(weatherObject);
печатает undefined. Что-то мне не хватает в том, как работают операторы .then ()?
Кроме того, автор snekfetch отказался от этого пакета и рекомендовал node-fetch в качестве альтернативы.
@Hydrothermal спасибо за ответ! Я обновил свой исходный вопрос, чтобы, надеюсь, прояснить, что я пытаюсь сделать, и какие результаты я получаю. Я знаю, что node-fetch предназначен для замены snekfetch, но я уже использую последний в нескольких местах своего кода, и он отлично работает везде, поэтому я стараюсь избегать переключения, если могу.



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


Операторы .then() не заставляют программу ждать их завершения, они просто выполняют свой код после разрешения Обещать, к которому они прикреплены.
Это означает, что вы не можете надежно использовать значение, которое было установлено внутри обещания, потому что код после обещания, вероятно, будет выполнен до того, как это обещание разрешится.
Вы можете либо перенести остальной код внутри этого оператора .then(), либо использовать async/await.
.
Если вы находитесь внутри функции, вы можете объявить ее как async function:, что позволяет вам использовать внутри нее ключевое слово await. await заставляет программу ждать разрешения обещания и вместо обещания возвращает значение, которое вы использовали бы в функции .then().
Вот пример:
// Instead of using this:
function getResult(args) {
let [country, ...city] = args;
let url = `http://api.openweathermap.org/data/2.5/forecast?q=${city},${country}&units=metric&APPID=${config.weatherID};`;
var weatherObject;
snekfecth.get(url).then(response => {
weatherObject = response.body;
});
return weatherObject; // undefined :(
}
// You could write it like this:
async function getResult(args) {
let [country, ...city] = args;
let url = `http://api.openweathermap.org/data/2.5/forecast?q=${city},${country}&units=metric&APPID=${config.weatherID};`;
let response = await snekfecth.get(url);
var weatherObject = response.body;
return weatherObject; // right value
}
Это почти работает, но теперь значение weatherObject выводится на консоль как «Promise {<pending>}». Я все еще что-то упускаю?
Ой, неважно, заставил его работать, переместив остальной код в функцию getResult! Большое спасибо за помощь ^^
Рад слышать это :)
Не очевидно, что это не работает. Что не работает? Есть ошибка? В чем ценность
weatherObjectи чего вы от него ожидаете? Ваш код явно не сломан, поэтому без дополнительной информации вам сложно помочь.