递归获取请求

Recursive Fetch Request

我正在尝试编写一个递归获取函数。我正在调用一个端点,它接受名称参数和 returns 它们的 role 和一个 direct-subordinates 数组,如下所示:

{
    role: "CEO",
    direct-subordinates: [ "john smith", "bob jones" ]
}

然后我想再次调用该函数为每个下属请求相同的数据。

这是我的代码:

export const fetchEmployee = async (name) => {
  let url = `https://url.com/to/employees/endpoint/${name}`
  let req = await fetch(url)
  let json = await req.json()
  return json
}

export const recursiveFetchEmployees = async (initialName) => {
  let json = await fetchEmployee(initialName)
  const role = json[0]
  const subordinates = json[1]
  if (subordinates) {
    return {
      name: initialName,
      role: role,
      subordinates: subordinates['direct-subordinates'].map(async (subordinate) => {
        let result = await recursiveFetchEmployees(subordinate)
        return result
      }),
    }
  } else {
    return {
      name: initialName,
      role: role,
    }
  }
}

这几乎可以用 recursiveFetchEmployees(employeeName).then((resp) => console.log(resp)) 调用,但结果是:

name: "robert robertson",
role: "CEO",
subordinates: (2) [Promise, Promise],

我该如何更改它,以便该函数在员工层次结构中向下运行,递归地产生如下结果:

{
    name: "robert robertson",
    role: "CEO",
    subordinates: [
        {
            name: "john smith",
            role: "Marketing Manager",
            subordinates: [{
                name: "mary doyle",
                role: "employee",
            }]
        },
        {
            name: "bob jones",
            role: "Development Manager",
            subordinates: [{
                name: "barry chuckle",
                role: "Development Lead",
                subordinates: [{
                    name: "billy bob",
                    role: "Developer",
                }]
            }]
        },
    ],
}

在此先感谢您的帮助或建议。

编辑/更新

感谢@trincot 给出的很好的回答,我遇到的问题得到了解决,但它引入了另一个问题。我需要检查并过滤掉返回结果中的重复项。我引入了一个 uniqueNameArray ,它用一个空数组初始化,并且在每次调用时,如果数组中尚不存在当前 initialName 参数的名称,它就会添加它。这是我的代码:


export const recursiveFetchEmployees = async (initialName, uniqueNameArray = []) => {
  if (!uniqueNameArray.includes(initialName)) {
    uniqueNameArray.push(initialName)
    let json = await fetchEmployee(initialName)
    const role = json[0]
    const subordinates = json[1]
    if (subordinates) {
      return {
        name: initialName,
        role: role,
        subordinates: await Promise.all(
          subordinates['direct-subordinates'].map(
            (subordinate) => subordinate && recursiveFetchEmployees(subordinate, uniqueNameArray)
          )
        ),
      }
    } else {
      return {
        name: initialName,
        role: role,
      }
    }
  }
}

不幸的是,当存在重复项时,它仍会在 map 函数中被调用,从而导致 subordinates 数组如下所示:

    {
       name: "bob jones",
       role: "Development Manager",
       subordinates: [
           {
               name: "barry chuckle",
               role: "Development Lead",
                   subordinates: [{
                      name: "billy bob",
                      role: "Developer",
                   }]
           },
           {
               name: "james jameson",
               role: "Development Lead",
                   subordinates: [{
                      name: "joey joe joe junior",
                      role: "Developer",
                   }]
            },
            undefined,   // <-- This is where there was a duplicate
         ]
     },

有没有办法将它从承诺列表中省略?据我所知,我上面所做的应该做到这一点,所以我不确定为什么它仍然是 returns 未定义的响应。

一如既往,感谢任何帮助,谢谢!

毫不奇怪,.map(async ... returns promise 对象数组,作为 async 函数总是 returns 一个 promise。

您可以在此处使用 Promise.all

subordinates: await Promise.all(
    subordinates['direct-subordinates'].map(recursiveFetchEmployees)
),

另请注意,您可以将 recursiveFetchEmployees 作为回调参数传递给 .map。无需创建包装函数。