.forEach()
does not wait for your async callback. It just merrily continues through its loop and you log the value of courses
and then sometime later, all the await
operations inside your callback finish and you put the values into courses
. So, it's a matter of timing where you're looking at the variable before the data has been put in it.
It's worth understanding that await
pauses ONLY the local function execution (the closest function scope) which in your case is the .forEach()
callback. It doesn't cause anything at a higher level to pause. And, since .forEach()
does not even look at what your callback returns, it's certainly not looking at the promise that the async
callback returns. So, as soon as you hit the await
, your async
callback returns a promise. The .forEach()
loop sees the callback return and immediately launches the next iteration of the loop even though your await
inside the callback has not yet finished.
It's important to understand that await
ONLY pauses the local function, not anything above it, not any callers. At the moment your async
function hits its first await
, that function returns a promise to the outside world. For the outside world to pause also, it has to do something with that promise which .forEach()
does not.
A for
loop, in the other hand, keeps the await
inside your actual function so the whole scope is paused with the await
.
If you want a loop to actually pause with an await
, then use a for
loop, not a .forEach()
loop.
For example, you could do this:
async fetch({store, error}) {
let series = '', courses = [], album = {};
for (let course of store.state.courses) {
album = {...course}
series = course.uri.split('/')[2]
try {
const {data: {data}} = await axios.get('http://localhost:3000/luvlyapi/videos', {
params: {
series //? album id
}
})
album['videos'] = data
courses.push(album)
console.log('loop', courses)
} catch (err) {
error({
statusCode: err.statusCode,
message: err
})
}
}
console.log({courses})
store.commit('SET_COURSES', courses)
}
FYI, your original implementation also has a problem with sharing higher level scoped variables among multiple async callbacks that are all in flight at the same time which will cause one to stomp on the other. The solution to that is to either do like my code example shows and serialize the async calls so they aren't in flight at the same time or declare the variables to be local to the async scope so each async callback has its own, separate variables.