javascript - 递归获取请求
问题描述
我正在尝试编写一个递归获取函数。我正在调用一个接受名称参数并返回它们的端点和一个类似这样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
用空数组初始化的 a ,并且在每次调用时,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
]
},
有没有办法从承诺列表中省略它?据我所知,我上面所做的应该做到这一点,所以我不确定为什么它仍然返回未定义的响应。
一如既往,感谢任何帮助,谢谢!
解决方案
.map(async ...
返回一个 Promise 对象数组并不奇怪,因为async
函数总是返回一个 Promise。
你可以Promise.all
在这里使用:
subordinates: await Promise.all(
subordinates['direct-subordinates'].map(recursiveFetchEmployees)
),
另请注意,您可以将recursiveFetchEmployees
作为回调参数传递给.map
. 无需创建该包装函数。