最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin2浏览0评论

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. The code:

const fetchData = async () => {
  const res = await fetch('');
  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 ponent and called it when the ponent did mount. But this time I got a Promise instead of the actual data. The code:

api.js:

export const fetchData = async () => {
  const res = await fetch(
    ";
  );
  const data = await res.json();
  return data;
};

App.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 ponent, it will retun 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 actual data?

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. 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 ponent and called it when the ponent did mount. But this time I got a Promise instead of the actual data. The code:

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:

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 ponent, it will retun 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 actual data?

Share asked Aug 28, 2022 at 19:09 JavaScript RookieJavaScript Rookie 2532 gold badges7 silver badges13 bronze badges 1
  • In your top version you are calling fetchData and inside that function you console loged the data after the promise was resolved. In your react app you are assigning the return value to a constant and then console logging the data. The return value of an async function is always a promise. developer.mozilla/en-US/docs/Web/JavaScript/Reference/… – Robert Commented Aug 28, 2022 at 19:18
Add a ment  | 

3 Answers 3

Reset to default 4

If you return the data in the first case and the log it, it will behave in the same way as case 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.

You're not paring 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.

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. 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?

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().

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)

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.

Even if the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a 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.

Please see docs for more reference

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论