问题
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