Reputation:
I have been searching for an answer for 3 days, so, I finally decided to ask by myself. I am using Nuxt JS and Riot API, and am new to both of them. I want to get data, then return it to store it inside another variable I could use later on. When I try to console log the data directly from inside my function, it works and I can see the data I want. But when I try to return it, it gives me this answer
Here is my function
mounted() {
console.log(this.fetchSomething())
},
methods: {
async fetchSomething() {
const test = await this.$axios.get('/api/')
.then((res) => {
return res.data;
})
console.log(test) // this works
return test // this gives me a pending promise
},
}
UPDATE
Thanks to jfriend00 for his amazing answer, correcting my code but most importantly explaining me what was wrong. I have now a better understanding of my mistake.
Corrected code
async mounted() {
const gettest = await this.fetchSomething()
console.log(gettest)
},
methods: {
async fetchSomething() {
const test = await this.$axios.get('/api/');
//console.log(test.data);
return test.data;
},
},
Upvotes: 1
Views: 4969
Reputation: 707198
All async
function return a promise. The return value inside the async
function becomes the resolved value of that returned promise. If there is an await
inside the async
function, then the function returns a promise as soon as the interpreter encounters the first await
in the function. If there are not await
statements in the function, it still returns a promise that will be immediately resolved with whatever your return value is.
Keep in mind that await
suspends internal execution of the async
function. It does not stop the caller's execution. At that first await
, the caller gets a pending promise and the caller keeps executing. The caller MUST use await
or .then()
themselves to get the return value from an async
function.
Here's what happens inside your async
function step-by-step"
this.fetchSomething()
.this.$axios.get('/api/')
is executed and it returns a promise and then the interpreter processes the await thatPromise
. At that first await
, the function execution is suspended and the function immediately returns an unresolved and pending promise.console.log()
sees that pending promise as the function has now returnedaxios.get().then(...)
finishes and resolves the promise it returns so the await
is done and assigned the resolved value of that axios.get().then()
promise to your variable test
. The value in test
is the result of your return value in .then()
test
and then you return the value of test
.async
function and that promise then gets resolved with that value.If you look carefully at your two console.log()
statements, you will see that this one console.log(this.fetchSomething())
happens first because that's where the function hit the await
and then immediately returned the pending promise. Your second console.log(test)
happens later after the await
is done waiting for the axios promise.
FYI, many people prefer not to mix await
and .then()
(though this doesn't change the outcome you were asking about - it's just a style issue) and you could write your function like this:
methods: {
async fetchSomething() {
const test = await this.$axios.get('/api/');
console.log(test.data);
return test.data;
},
}
or, even this:
methods: {
async fetchSomething() {
const {data} = await this.$axios.get('/api/');
console.log(data);
return data;
},
}
Upvotes: 4