I have an object, that has a nested array of objects, which has another nested array of objects. I have an asynchronous function that checks if they are valid. I want it to run concurrently, but I want to wait on all of the promises to return. Right now I have:
function validate(userId): Promise<User> {
let user = await this.userRepo.findById(input).catch(err => this.handleNotExistent(err))
let friends = user.friends || []
await Promise.all(friends.map(async friend => {
let validFriend = await this.friendRepo.findById(friend.id).catch(err => this.handleNotExistent(err))
if (validFriend.name != friend.name || validFriend.age != friend.age) {
this.handleInvalidRequest()
}
else {
let friendOfFriends = friend.friendOfFriends || []
return await Promise.all(friendOfFriends.map(async friendOfFriend => {
let validFOF = await this.FOFRepo.findById(friendOfFriend.id).catch(err => this.handleNotExistent(err))
if (validFOF.name != friendOfFriend.name) {
this.handleInvalidRequest()
}
else {
return validFOF
}
}
}
}
How can I rewrite this, so that it runs in order (you need to find validFriend first before you can look up their friendOfFriend, but all of the mapped items run concurrently?
You have two problems:
It would have been ideal if you could have made the code standalone and runnable on the TypeScript playground (obviously, you'd have to make this a simplified version of the real thing), because then it'd be easier to show you unwinding it.
But in spirit, the first approach I'd take would be like:
async function validate(userId): Promise<User> {
...
let friends = await findFriendsAndTheirFriends(userId)
return Promise.all(friends.map(validateFriend))
}
The first function, findFriendsAndTheirFriends()
(you'd have to write that, of course), takes a given user ID and returns a list of friends and their friends. The second function takes each friend userId
and returns a promise that will validate that friend.
But I don't think the way you've got exactly two levels of friends is good. Aside from being hard to read, it's very inflexible, and near impossible to debug.
You'd be better off turning it into some kind of graph problem, where you search for all nodes (user IDs) connected to your node (your user) by a distance < 3.
The beauty of that approach is that it would still work with the code above, just that the findFriendsAndTheirFriends()
function would do the graph search behind the scenes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With