Heim  >  Fragen und Antworten  >  Hauptteil

Titel umgeschrieben als: Rekursive asynchrone Funktion kann keinen Wert zurückgeben

<p>Ich erstelle eine rekursive asynchrone Funktion, die eine MySQL-Abfrage ausführt. Dies ist die Datenbank, die ich verwende: </p> <pre class="brush:php;toolbar:false;">+----+-------------------+------- ----+----------+-----------+---------------------+ |. id |. parentid | +----+-----------+-----------+----------+- -------- ---+--------------------+ |. 1 |. 0 |. 2022-03-24 | |. 2 |. 0 |. 2022-03-24 | |. 3 |. 0 |. 2022-03-24 | |. 4 |. 2022-03-24 | |. 5 |. 2022-03-24 | |. 6 |. 1 |. 2022-03-24 | |. 7 |. 0 |. 2022-03-24 | |. 8 |. 0 |. 2022-03-24 | |. 9 |. Den Müll rausbringen 1 |. 24.03.2022 | +----+-----------+-----------+----------+- -------- ---+--------------------+</pre> <p>Wenn ich diese Datenbank in einem Array speichere, kann ich diese Funktion ausführen: </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)); Rückgabeaufgabe }</pre> <p> um Unteraufgaben rekursiv in die Hauptaufgabe zu verschachteln. </p> <p>Das Problem ist, dass ich asynchrone Funktionen nicht gut genug verstehe.</p> <p>Das sind meine bisherigen Fortschritte: </p> <pre class="brush:php;toolbar:false;">asynchrone Funktion comp(taskId) { // SELECT * FROM task WHERE id = taskId var task = waiting con.promise().query('select * from task where id = ' + taskId) // SELECT * FROM task WHERE parentId = taskId var children = waiting con.promise().query('select * from task where parentid = ' + taskId) task[0][0].children = children[0].map(child => { comp(child.id) }) console.log(task[0]) }</pre> <p>Dies gibt jedoch eine Aufgabe mit undefinierten Unteraufgaben zurück: </p> <pre class="brush:php;toolbar:false;">[ { ID: 1, Aufgabe: „Wohnung aufräumen“, abgeschlossen: 0, parentid: null, erstellt von: 1, erstellt am: 23.03.2022T23:47:33.000Z, Kinder: [ undefiniert, undefiniert ] } ]</pre> <p>Kurz gesagt, ich möchte Folgendes: </p> <pre class="brush:php;toolbar:false;">{ ID: 1, Aufgabe: „Wohnung aufräumen“, abgeschlossen: 0, parentid: null, erstellt von: 1, erstellt am: 23.03.2022T23:47:33.000Z, Kinder: [ { ID: 2, Aufgabe: „Das Badezimmer putzen“, abgeschlossen: 0, Eltern-ID: 1, erstellt von: 1, erstellt am: 23.03.2022T23:47:33.000Z, Kinder: [ { ID: 4, Aufgabe: 'Dusche waschen', abgeschlossen: 0, Eltern-ID: 2, erstellt von: 1, erstellt am: 23.03.2022T23:47:33.000Z, Kinder: [ ... ] }, { ID: 5, Aufgabe: „Toilette waschen“, abgeschlossen: 0, Eltern-ID: 2, erstellt von: 1, erstellt am: 23.03.2022T23:47:33.000Z, Kinder: [ ... ] }, ] }, { ID: 3, Aufgabe: „Küche putzen“, abgeschlossen: 0, Eltern-ID: 1, erstellt von: 1, erstellt am: 23.03.2022T23:47:33.000Z, Kinder: [ ... ] }, }</pre> <p>Irgendwelche Vorschläge? </p>
P粉729518806P粉729518806391 Tage vor485

Antworte allen(2)Ich werde antworten

  • P粉970736384

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

    您正在等待原始的两个期待的项目完成运行,然后开始下一个递归调用,然后打印而不等待递归调用本身。

    首先,您需要

    await comp(child.id);

    但您还需要等待每个子项完成运行。

    Promise.all(array)

    将等待您传递给它的数组中的每个承诺完成,而children[0].map(async () => {})将返回一个承诺数组。继续等待它,您应该就可以了。

    Antwort
    0
  • P粉596191963

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

    Antwort
    0
  • StornierenAntwort