Fetch API always returning a promise

末鹿安然 提交于 2021-02-17 05:54:53

问题


I have the following code where I am calling an api


    const fetchToken = async () => {
      const response = await axios.post("http://localhost:3000/api/getRedisData", 
      {
        key: process.env.AUTH_TOKEN_NAME!,
      });
      console.log(response); // this returns what I expect it to return
      return response;
    };

Then I am calling the function like this.


    fetchToken();

Now, this function works just fine. But when I try to save the data of this response like the following.


    token = fetchToken().then((r) => r);

It returns a promise and it never resolves. What is happening and how do I wait until this promise resolves. I just need to wait and get the data. Thanks in advance.

I updated this question.

Let's suppose I have the following object.

    const authMachine = createMachine<toggleAuth>({
      id: "auth",
      initial: "unauthenticated", // I want to chage this value based on token
      context: {
        //
      },
      states: {
        //
      },
    });

Now I want to update the initial property based on if I am getting a token or not. Right now I am doing something like this.

    initial: token ? "authenticated" : "unauthenticated"

So what's wrong here?


回答1:


All async functions return a promise. So your fetchToken() function will always return a promise. The resolved value of that promise will be whatever value you return from the fetchToken() function body.

So, the caller of fetchToken() has to use await or .then() to get that resolved value. There is no free lunch with async/await. It's still asynchronous. await gives you synchronous-like behavior inside the function, but not outside the function.

To explain a little further. As fetchToken() executes, as soon as it hits the first await, it immediately suspends further execution of the function body and then immediately returns an unresolved promise back to the caller. The caller then continues to execute and the caller has to use .then() or await to know when the body of fetchToken() is actually done and what its final returned value is.

Then, sometime later, the promises you used await on inside of fetchToken() will resolve or reject and when the JS interpreter is back to the event loop, then it will continue executing the rest of the body of fetchToken() after the await. When it finally gets to the end of the function body or encounters a return statement, then it resolves the promise that was previously returned and the caller that is using either await or .then() will get notified that it is done and will be given the final return value as the resolved value of that promise. The caller can then process that final value and do its thing.

So, you probably want to be using something like this to get the final value or the error:

fetchToken().then(token => {
    console.log(token);
    // use the token value here
}).catch(err => {
    console.log(err);
});
// you cannot use the token value here

If the call to fetchToken() itself is inside an async function, then it can use await also:

try {
    let token = await fetchToken();
    console.log(token);
    // use the token value here
} catch(err) {
    console.log(err);
}



回答2:


If you are in an async function, you can just await it to get the data.

const token = await fetchToken();
console.log(token);
// do other stuff with token

If you aren't, then you need to do everything you want done with the token in your then method. This is because you are calling an async method and without the ability to await it. The execution will just continue. The then function is the callback that happens when your async method completes successfully.

fetchToken().then(token => {
  console.log(token)
  // do other stuff with token
});


来源:https://stackoverflow.com/questions/65165098/fetch-api-always-returning-a-promise

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!