ホームページ  >  に質問  >  本文

タイトルは次のように書き換えられました: 再帰的非同期関数は値を返せません

<p>mysql クエリを実行する再帰的非同期関数を作成しています。これは私が使用しているデータベースです: </p> <pre class="brush:php;toolbar:false;"> ---- ------------------- ---------- - ---------- ---------- ----------------------- | ID | タスク | 完了 | 親 ID | 作成者 | 作成場所 | ---- ------------------- ----------- ---------- ------ ------------------------ | 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 = task.find(task => task.id === taskId) var Children = task.filter(t => t.parentId === taskId) task.children = Children.map(child => comp(tasks, child.id)); タスクを返す }</pre> <p> サブタスクをメイン タスクに再帰的にネストします。 </p> <p>問題は、非同期関数を十分に理解していないことです。</p> <p>これまでの私の進捗状況は次のとおりです: </p> <pre class="brush:php;toolbar:false;">async 関数 comp(taskId) { // SELECT * FROM タスク WHERE id = taskId var task = await con.promise().query('select * from タスク where id = ' taskId) // SELECT * FROM タスク WHEREparentId = taskId var Children = await con.promise().query('select * from タスク whereparentid = ' taskId) task[0][0].children = Children[0].map(child => { comp(child.id) }) console.log(タスク[0]) }</pre> <p>しかし、これは未定義のサブタスクを含むタスクを返します: </p> <pre class="brush:php;toolbar:false;">[ { ID:1、 タスク: 「アパートを掃除する」、 完了: 0、 親ID: null、 作成者: 1、 作成日: 2022-03-23T23:47:33.000Z、 子: [未定義、未定義] } ]</pre> <p>簡単に言うと、私が欲しいのは次のとおりです: </p> <pre class="brush:php;toolbar:false;">{ ID:1、 タスク: 「アパートを掃除する」、 完了: 0、 親ID: null、 作成者: 1、 作成日: 2022-03-23T23:47:33.000Z、 子供たち: [ { ID:2、 タスク: 「バスルームを掃除する」、 完了: 0、 親ID: 1、 作成者: 1、 作成日: 2022-03-23T23:47:33.000Z、 子供たち: [ { ID:4、 タスク: 'シャワーを洗う'、 完了: 0、 親ID: 2、 作成者: 1、 作成日: 2022-03-23T23:47:33.000Z、 子供たち: [ ... ] }、 { ID:5、 タスク: 「トイレを洗う」、 完了: 0、 親ID: 2、 作成者: 1、 作成日: 2022-03-23T23:47:33.000Z、 子供たち: [ ... ] }、 】 }、 { ID:3、 タスク: 「キッチンを掃除する」、 完了: 0、 親ID: 1、 作成者: 1、 作成日: 2022-03-23T23:47:33.000Z、 子供たち: [ ... ] }、 }</pre> <p>何か提案はありますか? </p>
P粉729518806P粉729518806391日前486

全員に返信(2)返信します

  • P粉970736384

    P粉9707363842023-08-30 12:38:29

    元の 2 つの予期された項目の実行が完了するのを待ってから次の再帰呼び出しを開始し、再帰呼び出し自体を待たずに印刷します。

    まず必要なものは

    リーリー

    ただし、各子供が走り終わるまで待つ必要もあります。

    リーリー

    は、渡された配列内の各 Promise が完了するまで待機しますが、children[0].map(async () => {}) は Promise の配列を返します。そのまま待っていれば大丈夫です。

    返事
    0
  • P粉596191963

    P粉5961919632023-08-30 10:50:07

    実は、コードの唯一の問題は、非同期関数 comp() からの結果を待っていないことです。 map() は Promise の配列を返します。これらすべての Promise を待つ必要があります。これを実現するには、Promise.all() を使用します。 Promise.all() Promise.all() に渡された配列内のすべての Promise が解決されたときに解決される Promise を返します。それを待っていれば、期待どおりに子の配列が伝播されます。

    これは Promise.all() を使用したコードです。現在、適切なデータベースの準備ができていないため、すべてのデータベースの非同期呼び出しを、人為的な遅延を伴う関数への非同期呼び出しに置き換えました。これにより、呼び出しがどのように待機されているか、および結果が実際に待機されているかどうかを確認できます。のために。

    リーリー

    返事
    0
  • キャンセル返事