Javascript 如何在嵌套映射函数中进行并发异步调用
我有一个对象,它有一个嵌套的对象数组,它有另一个嵌套的对象数组。我有一个异步函数来检查它们是否有效。我希望它同时运行,但我想等待所有的承诺返回。现在我有:Javascript 如何在嵌套映射函数中进行并发异步调用,javascript,typescript,promise,async-await,Javascript,Typescript,Promise,Async Await,我有一个对象,它有一个嵌套的对象数组,它有另一个嵌套的对象数组。我有一个异步函数来检查它们是否有效。我希望它同时运行,但我想等待所有的承诺返回。现在我有: function validate(userId): Promise<User> { let user = await this.userRepo.findById(input).catch(err => this.handleNotExistent(err)) let friends = user.friends
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
}
}
}
}
函数验证(userId):承诺{
让user=wait this.userRepo.findById(input.catch)(err=>this.handleNotExistent(err))
让朋友=user.friends | |[]
等待Promise.all(friends.map)(异步friend=>{
让validFriend=等待this.friendRepo.findById(friend.id).catch(err=>this.handleNotExistent(err))
if(validFriend.name!=friend.name | | validFriend.age!=friend.age){
这个。handleInvalidRequest()
}
否则{
让friendOfFriends=friend.friendOfFriends | |【】
return wait Promise.all(friendOfFriends.map)(异步friendOfFriend=>{
让validFOF=等待this.FOFRepo.findById(friendOfFriend.id).catch(err=>this.handleNotExistent(err))
if(validof.name!=friendOfFriend.name){
这个。handleInvalidRequest()
}
否则{
返回有效期
}
}
}
}
如何重写它,使其按顺序运行(您需要先找到validFriend,然后才能查找他们的friendOfFriend,但所有映射项都同时运行?您有两个问题:
async function validate(userId): Promise<User> {
...
let friends = await findFriendsAndTheirFriends(userId)
return Promise.all(friends.map(validateFriend))
}
异步函数验证(userId):承诺{
...
let friends=等待找到的朋友和他们的朋友(userId)
返回Promise.all(friends.map(validateFriend))
}
第一个函数,findFriendsAndTheirFriends()
(当然,您必须编写该函数),获取给定的用户ID并返回朋友及其朋友的列表。第二个函数获取每个朋友的userId
,并返回一个将验证该朋友的承诺
但是我不认为你有两个级别的朋友的方式是好的。除了难以阅读之外,它非常死板,几乎不可能调试
最好将其转化为某种图形问题,搜索与节点(用户)连接的距离小于3的所有节点(用户ID)
这种方法的美妙之处在于它仍然可以与上面的代码一起工作,只是
FindFriends和TheirFriends()
函数可以在后台进行图形搜索。现在,两个映射的承诺已经并行运行。1)顶级承诺。所有都在friends
上,2)嵌套的Promise.all
在friendOfFriends
上,并且您的其他条件也得到满足:“首先查找validFriend
,然后才能查找他们的friendOfFriend
”。需要记住的一点是,函数签名显示返回的是Promise
,但目前没有返回任何内容。抱歉,我在结尾排除了return语句。因此所有的好友都是同时验证的,而不是按顺序验证的?@VikramKhemlani是的,它是同时运行的。看起来没有任何wrong使用此代码。您可以将!=
转换为!=
。这完全取决于您希望作为最终输出的内容。目前,您将得到一个包含朋友数组的数组,但不会尝试在任何级别筛选出无效朋友。每个级别都返回一个已验证朋友数组是有意义的属性包含一个已验证的朋友数组(即每个朋友的已验证朋友)。如果这是您想要的,那么您需要为每个映射执行两项操作(1)返回朋友,如果有效,或者返回错误(例如null
),如果无效(不要抛出),然后(2)过滤映射数组以清除空值,只留下有效的朋友。您还需要将每个朋友的已验证朋友附加为原始朋友的属性。谢谢Andrew!但是“查找朋友”和“他们的朋友”不是同一个映射函数吗?(通过循环查找朋友和他们的朋友)。如果我返回一个对象数组,该数组具有嵌套数组(朋友和朋友的朋友),我将抛出相同的信息两次,首先是为了查找,然后是为了验证?另外,您是否有任何指向绘图函数的链接,我似乎找不到任何东西,我使用的是postgres,这是一个关系数据库,因此“没有图”。@VikramKhemlani,如问题中所述,第一级和第二级之间有三个区别vel验证:(i)存储未验证好友的用户属性.friends
vs.friendOfriends
(ii)repo“friendRepo”vs“FOFRepo”。(iii)朋友属性已验证,.name&.age
vs.name
。如果您希望通过同一功能查找朋友和朋友中的朋友,则需要在总体设计中定位或消除这些差异。