我正在制作一个递归异步函数,该函数正在运行一个mysql查询。这是我正在使用的数据库:
+----+-------------------+-----------+----------+-----------+---------------------+ | id | task | completed | parentid | createdby | createdat | +----+-------------------+-----------+----------+-----------+---------------------+ | 1 | 清洁公寓 | 0 | NULL | 1 | 2022-03-24 00:47:33 | | 2 | 清洁浴室 | 0 | 1 | 1 | 2022-03-24 00:47:33 | | 3 | 清洁厨房 | 0 | 1 | 1 | 2022-03-24 00:47:33 | | 4 | 洗淋浴器 | 0 | 2 | 1 | 2022-03-24 00:47:33 | | 5 | 洗马桶 | 0 | 2 | 1 | 2022-03-24 00:47:33 | | 6 | 清洁玻璃窗格 | 1 | 4 | 1 | 2022-03-24 00:47:33 | | 7 | 清洁水龙头 | 0 | 4 | 1 | 2022-03-24 00:47:33 | | 8 | 清洁水槽 | 0 | 3 | 1 | 2022-03-24 00:47:33 | | 9 | 倒垃圾 | 1 | 3 | 1 | 2022-03-24 00:47:33 | +----+-------------------+-----------+----------+-----------+---------------------+
如果我将这个数据库存储在一个数组中,我可以运行这个函数:
function comp(tasks, taskId) { var task = tasks.find(task => task.id === taskId) var children = tasks.filter(t => t.parentId === taskId) task.children = children.map(child => comp(tasks, child.id)); return task }
来递归地将子任务嵌套到主任务中。
问题是我对异步函数的理解不够好。
这是我目前的进展:
async function comp(taskId) { // SELECT * FROM tasks WHERE id = taskId var task = await con.promise().query('select * from tasks where id = ' + taskId) // SELECT * FROM tasks WHERE parentId = taskId var children = await con.promise().query('select * from tasks where parentid = ' + taskId) task[0][0].children = children[0].map(child => { comp(child.id) }) console.log(task[0]) }
但是这返回了带有未定义子任务的任务:
[ { id: 1, task: '清洁公寓', completed: 0, parentid: null, createdby: 1, createdat: 2022-03-23T23:47:33.000Z, children: [ undefined, undefined ] } ]
简而言之,我希望得到的结果如下:
{ id: 1, task: '清洁公寓', completed: 0, parentid: null, createdby: 1, createdat: 2022-03-23T23:47:33.000Z, children: [ { id: 2, task: '清洁浴室', completed: 0, parentid: 1, createdby: 1, createdat: 2022-03-23T23:47:33.000Z, children: [ { id: 4, task: '洗淋浴器', completed: 0, parentid: 2, createdby: 1, createdat: 2022-03-23T23:47:33.000Z, children: [ ... ] }, { id: 5, task: '洗马桶', completed: 0, parentid: 2, createdby: 1, createdat: 2022-03-23T23:47:33.000Z, children: [ ... ] }, ] }, { id: 3, task: '清洁厨房', completed: 0, parentid: 1, createdby: 1, createdat: 2022-03-23T23:47:33.000Z, children: [ ... ] }, }
有什么建议吗?
您正在等待原始的两个期待的项目完成运行,然后开始下一个递归调用,然后打印而不等待递归调用本身。
首先,您需要
但您还需要等待每个子项完成运行。
将等待您传递给它的数组中的每个承诺完成,而
children[0].map(async () => {})
将返回一个承诺数组。继续等待它,您应该就可以了。实际上,你的代码唯一的问题是你没有等待来自异步函数
comp()
的结果。map()
将返回一个Promise数组,你需要等待所有这些Promise,可以使用Promise.all()
来实现。Promise.all()
返回一个Promise,当传递给Promise.all()
的数组中的所有Promise都被解决时,该Promise将被解决。如果你等待它,你的children数组将按照你的期望传播。这是使用
Promise.all()
的代码。因为我目前没有一个合适的数据库准备好,所以我用一个具有人工延迟的函数的异步调用替换了你所有的数据库异步调用,这样你就可以看到如何等待这些调用以及结果是否被真正等待。