#javascript #asynchronous #async-await #get #fetch
#javascript #асинхронный #асинхронный-ожидание #получить #принести
Вопрос:
Кодекс:
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
const raw = JSON.stringify({
email: "example@gmail.com",
password: "password",
});
const requestOptions = {
method: "POST",
headers: myHeaders,
body: raw,
redirect: "follow",
};
let data;
fetch("/users/login", requestOptions)
.then((response) => response.text())
.then((result) => {
data = JSON.parse(result);
})
.catch((error) => console.log("error", error));
console.log(data);
Результат, который я получаю, не определен.
Результат, который я хочу, — это объект результата из выборки, который будет сохранен в данных с помощью async / await.
Ответ №1:
Ваш вызов console.log
выполняется до завершения запроса и получения данных.
Порядок выполнения отличается от порядка написания вашего кода. Вероятная цепочка событий такова:
- Создайте неопределенную переменную с именем
data
- Запустите запрос
/users/login
с помощью fetch API, который будет выполняться асинхронно - Вызов
console.log
с ссылкой наdata
который все ещеundefined
- Запрос завершен, поэтому обратный вызов, переданный
fetch.then
, вызывается иdata
определяется
Вам нужно будет дождаться завершения запроса и анализа ответа, прежде чем что — то делать data
.
Вы можете сделать это несколькими различными способами. Использование обещаний:
let data;
fetch("/users/login", requestOptions)
.then((response) => response.text())
.then((result) => {
data = JSON.parse(result);
// Now that `data` has been defined, we can do something with it
console.log(data);
})
.catch((error) => console.log("error", error));
С помощью async / await
// Note the async keyword
async function foobar() {
let data;
// Note the await keyword
await fetch("/users/login", requestOptions)
.then((response) => response.text())
.then((result) => {
data = JSON.parse(result);
})
.catch((error) => console.log("error", error));
console.log(data);
}
// There are other improvements that could be made to this example also
// to make it more idiomatic. For example:
async function foobar() {
let data;
// Use try/catch instead of `Promise.catch`
try {
const response = await fetch('/users/login', requestOptions);
// Use the `.json` method on the fetch response object
data = await response.json();
} catch (error) {
console.log('error', error);
}
console.log(data);
}
Важно отметить, что любое действие, которое происходит в контексте обещания (в вашем случае присвоение data
будет происходить асинхронно. Действие может быть завершено, а может и не быть завершено в любой данный момент.
Использование async / await обычно рекомендуется в качестве наилучшей практики в наши дни. Для этого требуется поддержка ES6, но обычно это дается в 2020 году и на данный момент поддерживается в браузерах и узлах уже много лет.
Использование async / await позволяет вам писать асинхронный код без страшного «ада обратного вызова» обещаний и позволяет вам писать более выразительный и читаемый код, который ближе напоминает процедурный код.
Одна вещь, которую следует иметь в виду при использовании async / await, заключается в том, что await
ключевое слово может использоваться только в функции, которая помечена как асинхронная с async
ключевым словом, как в приведенном выше примере.
Ответ №2:
Вы не можете распечатать переменную, значение которой инициализировано в асинхронном блоке.
Данные будут напечатаны правильно, если вы изменили их таким образом.
fetch("/users/login", requestOptions)
.then((response) => response.text())
.then((result) => {
const data = JSON.parse(result);
console.log(data);
})
.catch((error) => console.log("error", error));
Итак, чтобы выполнить действие с этими данными, вы должны сделать это внутри блока then, поскольку это функция разрешения для этого обещания.
в противном случае вы можете использовать async/await
синтаксис, если он поддерживается. просто вы можете сделать это таким образом.
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
const raw = JSON.stringify({
email: "example@gmail.com",
password: "password",
});
const requestOptions = {
method: "POST",
headers: myHeaders,
body: raw,
redirect: "follow",
};
try{
const data = await fetch("/users/login", requestOptions);
console.log(data);
catch(err){
console.log('error', err);
}