如何在嵌套映射函数中进行并发异步调用

时间:2019-11-12 23:02:32

标签: 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 || []
  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
        }   
     }
   }
}


我该如何重写它,以使其按顺序运行(您必须先找到有效朋友,然后才能查找其friendOfFriend,但所有映射的项同时运行?

1 个答案:

答案 0 :(得分:1)

您有两个问题:

  1. 要解包的嵌套结构
  2. 如何等待多重承诺

如果可以使代码在TypeScript操场上独立并可以运行,那将是理想的选择(显然,您必须将其简化为真实的版本),因为那样会更容易显示你放开它。

但从本质上讲,我会采用的第一种方法是:

async function validate(userId): Promise<User> {
  ...
  let friends = await findFriendsAndTheirFriends(userId)
  return Promise.all(friends.map(validateFriend))
}

第一个函数findFriendsAndTheirFriends()(当然,您必须编写该函数)采用给定的用户ID并返回朋友及其朋友的列表。第二个函数接受每个朋友userId并返回一个可以验证该朋友的诺言。

但是我认为您拥有两个好友级别的方式并不好。除了难以阅读之外,它非常不灵活,几乎无法调试。

最好将其转变为某种图形问题,在其中搜索与节点(您的用户)连接的所有节点(用户ID)的距离小于3。

该方法的优点在于它仍然可以与上面的代码一起使用,只是findFriendsAndTheirFriends()函数可以在后台进行图形搜索。