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)); })();