我正在制作一個運行 mysql 查詢的遞回異步函式。這是我正在使用的資料庫:
---- ------------------- ----------- ---------- ----------- ---------------------
| id | task | completed | parentid | createdby | createdat |
---- ------------------- ----------- ---------- ----------- ---------------------
| 1 | Clean apartment | 0 | NULL | 1 | 2022-03-24 00:47:33 |
| 2 | Clean bathroom | 0 | 1 | 1 | 2022-03-24 00:47:33 |
| 3 | Clean kitchen | 0 | 1 | 1 | 2022-03-24 00:47:33 |
| 4 | Wash shower | 0 | 2 | 1 | 2022-03-24 00:47:33 |
| 5 | Wash toilet | 0 | 2 | 1 | 2022-03-24 00:47:33 |
| 6 | Clean glass panes | 1 | 4 | 1 | 2022-03-24 00:47:33 |
| 7 | Clean faucet | 0 | 4 | 1 | 2022-03-24 00:47:33 |
| 8 | Clean sink | 0 | 3 | 1 | 2022-03-24 00:47:33 |
| 9 | Take out trash | 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: 'Clean apartment',
completed: 0,
parentid: null,
createdby: 1,
createdat: 2022-03-23T23:47:33.000Z,
children: [ undefined, undefined ]
}
]
簡而言之,我正在尋找的結果如下所示:
{
id: 1,
task: 'Clean apartment',
completed: 0,
parentid: null,
createdby: 1,
createdat: 2022-03-23T23:47:33.000Z,
children: [
{
id: 2,
task: 'Clean bathroom',
completed: 0,
parentid: 1,
createdby: 1,
createdat: 2022-03-23T23:47:33.000Z,
children: [
{
id: 4,
task: 'Wash shower',
completed: 0,
parentid: 2,
createdby: 1,
createdat: 2022-03-23T23:47:33.000Z,
children: [ ... ]
},
{
id: 5,
task: 'Wash toilet',
completed: 0,
parentid: 2,
createdby: 1,
createdat: 2022-03-23T23:47:33.000Z,
children: [ ... ]
},
]
},
{
id: 3,
task: 'Clean kitchen',
completed: 0,
parentid: 1,
createdby: 1,
createdat: 2022-03-23T23:47:33.000Z,
children: [ ... ]
},
}
有小費嗎?
uj5u.com熱心網友回復:
本質上,您的代碼的唯一問題是您不等待 async function 的結果comp()。map()將回傳一個 Promises 陣列,您需要等待所有可以使用Promise.all(). Promise.all()回傳一個 Promise,它將在傳遞給的陣列中的所有 Promise 都解決后Promise.all()解決。如果您等待您的孩子陣列將按照您的預期傳播。
這是您的代碼 using Promise.all()。因為我目前沒有準備好合適的資料庫,所以我將所有對資料庫的異步呼叫替換為對內置人工延遲的函式的異步呼叫,因此您可以看到如何實際等待這些以及結果實際上是在等待。
const data = [
{
id: 1,
task: "Clean apartment",
completed: 0,
parentid: null,
createdby: 1,
createdat: "2022-03-24 00:47:33",
},
{
id: 2,
task: "Clean bathroom",
completed: 0,
parentid: 1,
createdby: 1,
createdat: "2022-03-24 00:47:33",
},
{
id: 3,
task: "Clean kitchen",
completed: 0,
parentid: 1,
createdby: 1,
createdat: "2022-03-24 00:47:33",
},
{
id: 4,
task: "Wash shower",
completed: 0,
parentid: 2,
createdby: 1,
createdat: "2022-03-24 00:47:33",
},
{
id: 5,
task: "Wash toilet",
completed: 0,
parentid: 2,
createdby: 1,
createDate: "2022-03-24 00:47:33",
},
{
id: 6,
task: "Clean glass panes",
completed: 1,
parentid: 4,
createdby: 1,
createdat: "2022-03-24 00:47:33",
},
{
id: 7,
task: "Clean faucet",
completed: 0,
parentid: 4,
createdby: 1,
createdat: "2022-03-24 00:47:33",
},
{
id: 8,
task: "Clean sink",
completed: 0,
parentid: 3,
createdby: 1,
createdat: "2022-03-24 00:47:33",
},
{
id: 9,
task: "Take out trash",
completed: 1,
parentid: 3,
createdby: 1,
createdat: "2022-03-24 00:47:33",
},
];
async function comp(tasks, taskId) {
// do your DB calls here (here just imitating the delay but the function are async to the result will remain the same)
var task = await queryFind(tasks, taskId);
var children = await queryFilter(tasks, taskId);
// map() returns an array of promises as comp() returns a promise
// Promise.all() returns a Promise that returns when all promises within the array are settled
task.children = await Promise.all(
children.map((child) => comp(tasks, child.id))
);
return task;
}
// this function immitates an async DB access.
async function queryFind(tasks, taskId) {
// wait for 100 milliseconds (imitate delay)
await sleep(100);
return tasks.find((task) => task.id === taskId);
}
// this function immitates an async DB access.
async function queryFilter(tasks, taskId) {
// wait for 100 milliseconds (imitate delay)
await sleep(100);
return tasks.filter((t) => t.parentid === taskId);
}
// delay execution. should imitage network delay here
async function sleep(ms) {
return new Promise((resolve) => setTimeout(() => resolve(), ms));
}
// Start at task with ID 1; need to wrap the function call in an async method to be able to use await
(async () => {
const test = await comp(data, 1);
console.log(JSON.stringify(test, null, 4));
})();
uj5u.com熱心網友回復:
您正在等待原來的兩個等待專案完成運行,然后開始下一個遞回呼叫,然后列印而不等待遞回呼叫本身。
首先,你會想要
await comp(child.id);
但是您也將要等待每個孩子完成跑步。
Promise.all(array)
將等待您傳入的陣列中的每個承諾完成,并且恰好children[0].map(async () => {})會回傳一組承諾。繼續前進并(a)等待,你應該準備好。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/450602.html
標籤:javascript mysql 节点.js 异步 递归
上一篇:在MySQL中,如果他們是我的朋友和所有公開帖子,我想帶上私人帖子
下一篇:MySQL第一個資料庫創建
