Heim > Fragen und Antworten > Hauptteil
P粉9707363842023-08-30 12:38:29
您正在等待原始的两个期待的项目完成运行,然后开始下一个递归调用,然后打印而不等待递归调用本身。
首先,您需要
await comp(child.id);
但您还需要等待每个子项完成运行。
Promise.all(array)
将等待您传递给它的数组中的每个承诺完成,而children[0].map(async () => {})
将返回一个承诺数组。继续等待它,您应该就可以了。
P粉5961919632023-08-30 10:50:07
实际上,你的代码唯一的问题是你没有等待来自异步函数comp()
的结果。 map()
将返回一个Promise数组,你需要等待所有这些Promise,可以使用Promise.all()
来实现。 Promise.all()
返回一个Promise,当传递给Promise.all()
的数组中的所有Promise都被解决时,该Promise将被解决。如果你等待它,你的children数组将按照你的期望传播。
这是使用Promise.all()
的代码。因为我目前没有一个合适的数据库准备好,所以我用一个具有人工延迟的函数的异步调用替换了你所有的数据库异步调用,这样你就可以看到如何等待这些调用以及结果是否被真正等待。
const data = [ { id: 1, task: "清洁公寓", completed: 0, parentid: null, createdby: 1, createdat: "2022-03-24 00:47:33", }, { id: 2, task: "清洁浴室", completed: 0, parentid: 1, createdby: 1, createdat: "2022-03-24 00:47:33", }, { id: 3, task: "清洁厨房", completed: 0, parentid: 1, createdby: 1, createdat: "2022-03-24 00:47:33", }, { id: 4, task: "洗淋浴器", completed: 0, parentid: 2, createdby: 1, createdat: "2022-03-24 00:47:33", }, { id: 5, task: "清洗马桶", completed: 0, parentid: 2, createdby: 1, createDate: "2022-03-24 00:47:33", }, { id: 6, task: "清洁玻璃窗", completed: 1, parentid: 4, createdby: 1, createdat: "2022-03-24 00:47:33", }, { id: 7, task: "清洁水龙头", completed: 0, parentid: 4, createdby: 1, createdat: "2022-03-24 00:47:33", }, { id: 8, task: "清洁水槽", completed: 0, parentid: 3, createdby: 1, createdat: "2022-03-24 00:47:33", }, { id: 9, task: "倒垃圾", completed: 1, parentid: 3, createdby: 1, createdat: "2022-03-24 00:47:33", }, ]; async function comp(tasks, taskId) { // 在这里执行你的数据库调用(这里只是模拟延迟,但函数是异步的,所以结果将保持不变) var task = await queryFind(tasks, taskId); var children = await queryFilter(tasks, taskId); // map()返回一个Promise数组,因为comp()返回一个Promise // Promise.all()返回一个Promise,当数组中的所有Promise都解决时返回 task.children = await Promise.all( children.map((child) => comp(tasks, child.id)) ); return task; } // 这个函数模拟了一个异步的数据库访问。 async function queryFind(tasks, taskId) { // 等待100毫秒(模拟延迟) await sleep(100); return tasks.find((task) => task.id === taskId); } // 这个函数模拟了一个异步的数据库访问。 async function queryFilter(tasks, taskId) { // 等待100毫秒(模拟延迟) await sleep(100); return tasks.filter((t) => t.parentid === taskId); } // 延迟执行,这里应该模拟网络延迟 async function sleep(ms) { return new Promise((resolve) => setTimeout(() => resolve(), ms)); } // 从ID为1的任务开始;需要将函数调用包装在一个异步方法中才能使用await (async () => { const test = await comp(data, 1); console.log(JSON.stringify(test, null, 4)); })();