异步发布父子对象和关系(递归?)



假设我正在尝试创建一个"家谱";作为一个JSON数组。

我有一个Person对象的数组

每个Person对象都有一个必选的name。每个对象也可以选择有一个children字段,包含一个数组的其他Person对象(也有一个children字段-所以"深度";家谱可以永远延续下去

如果没有子数组,children字段将只是一个空数组[]

const family_name = "The Numbers";
const family = [{
name: "1"
children: [],
},
{
name: "2"
children: [{
name: "2 - 1",
children: [],
},
{
name: "2 - 2",
children: [{
name: "2 - 2 - 1",
children: [],
}, ],
}
],
},
{
name: "3"
children: [{
name: "3 - 1",
children: [],
}, ],
},
]

我需要POST "parent"在"孩子"之前。当我发布Person时,我在response.data中得到它的id。这个id需要在直接子进程的POST中作为parent_id使用,这样子进程就会与父进程相关联。

我还需要POST "family_name"首先返回一个family_id。这个family_id将被用作parent_id,仅用于最顶层的Persons。

axios.post(FAMILY_URL, {"family_name": family_name})
.then((response) => {
// Promise.all() POST 1, 2, and 3 with their "parent_id" as response.data.family_id
// Promise.all() POST 2-1 and 2-2 with their "parent_id" as 2's response.data.id
// POST 2-2-1 with its "parent_id" as 2-1's response.data.id
// POST 3-1 with its "parent_id" as 3's response.data.id
})

但是如果Person对象的数量和深度未知,代码会是什么样子呢?我必须利用递归函数,对吧?

我还想对所有"兄弟姐妹"使用Promise.all()

您希望递归地遍历数据结构,沿途累积承诺

// fake axios, ignore this bit
const FAMILY_URL="family-url",axios={post:async(a,o)=>(console.log(`POST ${a}`,o),{data:{id:`${a===FAMILY_URL?"":`${o.parent_id}-`}${Math.ceil(100*Math.random())}`}})};
// resolves an individual person by posting their details with a given
// parent ID, then doing the same for any children
const savePerson = async (parent_id, { name, children }) => {
// get this person's ID
const { data: { id } } = await axios.post("person-url", {
name,
parent_id
})

return {
id, // assign the ID for visibility
name,
// pass this person's ID as the children's parent
children: await savePeople(id, children)
}
}
// resolves an array of people given a "parent ID"
const savePeople = (parent_id, people) =>
Promise.all(people.map(person => savePerson(parent_id, person)))
// Top-level family helper
const saveFamily = async (family_name, family) => {
const { data: { id } } = await axios.post(FAMILY_URL, { family_name })

// resolve all the people in the family array
return savePeople(id, family)
}
// minified
const family = [{"name":"1","children":[]},{"name":"2","children":[{"name":"2 - 1","children":[]},{"name":"2 - 2","children":[{"name":"2 - 2 - 1","children":[]}]}]},{"name":"3","children":[{"name":"3 - 1","children":[]}]}]
saveFamily("Smith", family).then(console.info)
.as-console-wrapper { max-height: 100% !important; }

我想方法用BFS算法。例子:

function postFamily(family) {
const queue = [];
queue.unshift(...family);
while (queue.length) {
const cur = queue.pop();
// HERE IS YOUR LOGIC RELATED TO THE CURRENT NODE
// FOR EXAMPLE:
axios.post('*FAMILY URL*', cur);
for (const child of cur) {
queue.unshift(child);
}
}
}
我不太清楚想要的结果,但我很高兴如果它能有所帮助。祝你今天愉快!

最新更新