简体   繁体   English

为什么我需要使用异步等待在 React 中调用异步 function 而在纯 JS 文件中不需要

[英]Why do I need to use async await to call a async function in React while it doesn't need in pure JS file

I did two tests:我做了两个测试:

The first test is in a pure JS file in which I called the async await function right after I created the function, it prints the correct data.第一个测试是在一个纯 JS 文件中,在我创建 function 之后,我在其中调用了异步等待 function,它打印了正确的数据。 The code:编码:

const fetchData = async () => {
  const res = await fetch('https://601caf791a9c220017060c02.mockapi.io/api/v1/Events');
  const data = await res.json();
  console.log(data);
}

fetchData()

While the second test I created the async await function inside a JS file in the React application, and then import that async function into another component and called it when the component did mount.在第二个测试中,我在 React 应用程序的 JS 文件中创建了异步等待 function,然后将该异步 function 导入另一个组件并在组件安装时调用它。 But this time I got a Promise instead of the actual data.但是这次我得到的是 Promise 而不是实际数据。 The code:编码:

api.js: api.js:

export const fetchData = async () => {
  const res = await fetch(
    "https://601caf791a9c220017060c02.mockapi.io/api/v1/Events"
  );
  const data = await res.json();
  return data;
};

App.js:应用程序.js:

import { useEffect } from 'react';
import { fetchData } from './api';

export default function App() {
  useEffect(() => {
    const results = fetchData();
    console.log(results);
  }, [])

  return (
    <div className="App">
      <h1>Hello world!</h1>
    </div>
  );
}

If I use another async await to call the fetchData function in the App component, it will retun the actual data.如果我使用另一个异步等待在App组件中调用fetchData function,它将返回实际数据。

I understand the async function will always return a Promise but why in the first test we don't need to add another async await when calling the fetchData function while it needs the async await to call the function inside the React application in order to get the actual data? I understand the async function will always return a Promise but why in the first test we don't need to add another async await when calling the fetchData function while it needs the async await to call the function inside the React application in order to get the实际数据?

If you return the data in the first case and the log it, it will behave in the same way as case 2.如果您在第一种情况下返回数据并记录它,它的行为方式与情况 2 相同。

    const fetchData = async () => {
  const res = await fetch('https://601caf791a9c220017060c02.mockapi.io/api/v1/Events');
  const data = await res.json();
  return data;
}

console.log(fetchData());

The reason the actual data is printed in the first case is that you are logging the data after first two lines when the promises are resolved.在第一种情况下打印实际数据的原因是您在解决承诺后的前两行之后记录数据。

For the second case, fetchData() is called which returns a promise because the promise is not resolved or rejected yet, then, immediately the next line is executed and the promise is logged because the promise is still not resolved or rejected. For the second case, fetchData() is called which returns a promise because the promise is not resolved or rejected yet, then, immediately the next line is executed and the promise is logged because the promise is still not resolved or rejected.

You're not comparing apples to apples.你不是在比较苹果和苹果。

In the first case, you're calling console.log(data) inside the async function, which doesn't care about the outside environment since its scope is async .在第一种情况下,您在async function 中调用console.log(data) ,它不关心外部环境,因为它的 scope 是async

With the other example, you're calling console.log on the return value of the function, which is a Promise because async functions always return promises.在另一个示例中,您在 function 的返回值上调用console.log ,这是一个Promise ,因为async函数总是返回承诺。 You are also calling console.log before the Promise is resolved, so how could you get any meaningful data if it doesn't exist yet?您还在解决Promise之前调用console.log ,那么如果它还不存在,您如何获得任何有意义的数据呢?

If you changed the first to如果您将第一个更改为

const fetchData = async () => {
  const res = await fetch('https://601caf791a9c220017060c02.mockapi.io/api/v1/Events');
  const data = await res.json();
  return data;
}

const data = fetchData();
console.log(data);

you'd get the same result as the second example.你会得到与第二个例子相同的结果。

If you want to get the actual data inside your useEffect , you need to either use async/await or .then() .如果要在useEffect中获取实际数据,则需要使用async/await.then()

import { useEffect } from 'react';
import { fetchData } from './api';

export default function App() {
  useEffect(() => {
    (async () => {
      const results = await fetchData();
      console.log(results);
    })();
  }, [])

  return (
    <div className="App">
      <h1>Hello world!</h1>
    </div>
  );
}

(note that the callback in useEffect itself cannot be async ) (注意useEffect本身的回调不能是async

It doesn't matter if the promise is resolved or not in async/await, a brand new Promise is returned which has to be resolved in the calling function which is not the case while using fetch if the returned value is resolved. promise 是否在 async/await 中被解析并不重要,一个全新的 Promise 被返回,它必须在调用 function 的情况下被解析,而如果使用返回的值没有被解析。

Even if the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise.即使异步 function 的返回值不是显式 promise,它也会隐式包装在 promise 中。

Thinks of it in layman's term as async makes the function return a new promise always whereas fetch just affects the variable which it returns.用外行人的话说,异步使 function 返回一个新的 promise 总是而 fetch 只影响它返回的变量。

Please see docs for more reference 请参阅文档以获取更多参考

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

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