如何使用async/await从fetch函数保存数据



代码:

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将fetch中的结果对象存储在数据中。

在请求完成和数据接收之前,对console.log的调用正在执行。

执行顺序与编写代码的顺序不同。可能的事件链是:

  • 创建名为data的未定义变量
  • 使用fetch API向/users/login发出请求,该请求将异步执行
  • 调用console.log并引用仍然是undefineddata
  • 请求已完成,因此调用传递给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));

带异步/等待

// 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年给出的,并且在浏览器和Node中已经支持了多年。

使用async/await可以让您编写异步代码,而不会出现可怕的";回调地狱";承诺,并允许你写更具表现力的&更像过程代码的可读代码。

使用async/await时需要记住的一点是,await关键字只能在与async关键字标记为异步的函数中使用,如上例所示。

不能打印其值在异步块中初始化的变量。

如果您将数据更改为那样,它将正确打印数据。

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块中执行,因为它是这个promise的解析函数。

否则,如果支持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);
}

最新更新