简体   繁体   English

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

[英]How can I save data from fetch function using async/await

The code:编码:

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);

The result I'm getting is undefined.我得到的结果是未定义的。 The result I want is result object from fetch to be stored in data with async/await.我想要的结果是来自获取的结果 object 以异步/等待存储在数据中。

Your call to console.log is being executed before the request has finished and the data has been received.您对console.log的调用是在请求完成并收到数据之前执行的。

The order of execution differs from the order your code is written.执行顺序与编写代码的顺序不同。 The likely chain of events is:可能的事件链是:

  • Create undefined variable named data创建名为data的未定义变量
  • Fire off a request to /users/login with the fetch API which will be executed asynchronously使用 fetch API 向/users/login发出请求,该请求将异步执行
  • Call to console.log with a reference to data which is still undefined调用console.log并引用仍未undefineddata
  • Request has completed, so the callback passed to fetch.then is called, and data is defined请求已完成,因此调用传递给fetch.then的回调,并定义data

You'd need to wait until the request is complete and the response is parsed before doing something with data .您需要等到请求完成并解析响应,然后再对data操作。

You can do this in a couple of different ways.您可以通过几种不同的方式执行此操作。 Using promises:使用承诺:

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));

With 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);
}

The important thing to note is that any action that occurs in the context of a promise (in your case, assignment to data will occur asynchronously . The action may or may not have been completed at any given moment.需要注意的重要一点是,在 promise 的上下文中发生的任何操作(在您的情况下,对data的分配将异步发生。该操作可能在任何给定时刻完成,也可能未完成。

Using async/await is usually recommend as best practice these days.如今,通常推荐使用 async/await 作为最佳实践。 This requires ES6 support, but that's usually a given in 2020 and has been supported in browsers and Node for years at this point.这需要 ES6 支持,但这通常是在 2020 年给定的,并且已经在浏览器和 Node 中支持多年。

Using async/await allows you to write asynchronous code without the dreaded "callback hell" of Promises, and allows you to write more expressive & readable code that closer resembles procedural code.使用 async/await 可以让您编写异步代码,而无需像 Promises 那样可怕的“回调地狱”,并允许您编写更具表现力和可读性的代码,更接近于过程代码。

One thing to bear in mind when using async/await is that the await keyword can only be used in a function that is marked as asynchronous with the async keyword, as in the above example.使用 async/await 时要记住的一件事是await关键字只能在使用async关键字标记为异步的 function 中使用,如上例所示。

You can't print a variable that its value initialized in asynchronous block.您不能打印其值在异步块中初始化的变量。

It will print the data correctly if you changed it to be like that.如果您将其更改为这样,它将正确打印数据。

fetch("/users/login", requestOptions)
  .then((response) => response.text())
  .then((result) => {
    const data = JSON.parse(result);
    console.log(data);
  })
  .catch((error) => console.log("error", error));

So to make an action to this data you have to do it inside the then block as it the resolve function for this promise.因此,要对这些数据执行操作,您必须在 then 块内执行此操作,因为它会为此 promise 解析 function。

otherwise, you can use the async/await syntax if it's supported.否则,如果支持,您可以使用async/await语法。 simply you can make it like that.只是你可以做到这一点。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM