I try rewrite it to Promise only style, but i got an empty result.
How it’s right way for rewrite it only use a Promise, without async/await
async getWishes() {
const wishes = await this.app.wishesService.getAllWishes()
for (const wish of wishes) {
const user = await this.app.userService.getUser(wish.userId)
wish.userName = user ? user.name : 'anonimus'
wish.userStars = user ? await this.app.favoriteService.getUserFavorites(user) : 0
}
return wishes
}
2
Answers
The for loop is the hard part. The easiest way to do it would be to push all the body of the for loop into an array and then do a
Promise.all()
:This is probably the simplest way to do it but it is not the same logic. In your original code the body of the for loop is waited for sequentially. That means there is only one query of
userService
andfavoriteService
going on for each iteration of the loop. In the code above we do it all in parallel. That means that all the queries are sent before any response formuserService
orfavoriteService
are received.To do it with exactly the same logic as your original code becomes more complicated because we cannot use a for loop. Instead we need to do some pseudo recursion ("pseudo: because we’re not really adding to the call stack, we’re replacing the function call with each loop):
This was what we had to do before async/await. It’s still possible to handle any level of complexity with just callbacks (eg. using the
.then()
method of a Promise) however as you can see it’s much simpler to do it with async/await.This following version ensures that all promises are resolved according to the order of the array (aka sequentially), which can otherwise have unexpected results since your code has side effects.
Though as you can probably tell, this code is a lot harder to read and reason about. So outside of educational purposes, stick mostly to using
async/await
🙂.