標題重寫為:遞歸非同步函數無法傳回值
P粉729518806
2023-08-29 21:11:13
<p>我正在製作一個遞歸非同步函數,該函數正在執行一個mysql查詢。這是我正在使用的資料庫:</p>
<pre class="brush:php;toolbar:false;"> ---- ------------------- ---------- - ---------- ----------- ---------------------
| 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 |
---- ------------------- ----------- ---------- ------ ----- --------------------- </pre>
<p>如果我將這個資料庫儲存在一個陣列中,我可以執行這個函數:</p>
<pre class="brush:php;toolbar:false;">function comp(tasks, taskId) {
var task = tasks.find(task => task.id === taskId)
var 孩子 = tasks.filter(t => t.parentId === taskId)
task.children = children.map(child => comp(tasks, child.id));
return task
}</pre>
<p>來遞歸地將子任務嵌套到主任務中。 </p>
<p>問題是我對非同步函數的理解不夠好。</p>
<p>這是我目前的進展:</p>
<pre class="brush:php;toolbar:false;">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 = 孩子[0].map(child => {
comp(child.id)
})
console.log(task[0])
}</pre>
<p>但這回傳了帶有未定義子任務的任務:</p>
<pre class="brush:php;toolbar:false;">[
{
id: 1,
task: '清潔公寓',
completed: 0,
parentid: null,
createdby: 1,
createdat: 2022-03-23T23:47:33.000Z,
children: [ undefined, undefined ]
}
]</pre>
<p>簡而言之,我希望得到的結果如下:</p>
<pre class="brush:php;toolbar:false;">{
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: [ ... ]
},
}</pre>
<p>有什麼建議嗎? </p>
您正在等待原始的兩個期待的項目完成運行,然後開始下一個遞歸調用,然後列印而不等待遞歸調用本身。
首先,您需要
但您還需要等待每個子項目完成運行。
將等待您傳遞給它的陣列中的每個承諾完成,而
children[0].map(async () => {})
將傳回一個承諾陣列。繼續等待它,您應該就可以了。實際上,你的程式碼唯一的問題是你沒有等待來自非同步函數
comp()
的結果。map()
將會傳回一個Promise數組,你需要等待所有這些Promise,可以使用Promise.all()
來實作。Promise.all()
傳回一個Promise,當傳遞給Promise.all()
的陣列中的所有Promise都被解決時,該Promise將被解決。如果你等待它,你的children數組將按照你的期望傳播。這是使用
Promise.all()
的程式碼。因為我目前沒有一個合適的資料庫準備好,所以我用一個具有人工延遲的函數的非同步調用替換了你所有的資料庫非同步調用,這樣你就可以看到如何等待這些調用以及結果是否真正等待。