Maison  >  Questions et réponses  >  le corps du texte

Titre réécrit comme : La fonction asynchrone récursive ne peut pas renvoyer de valeur

<p>Je crée une fonction asynchrone récursive qui exécute une requête MySQL. Voici la base de données que j'utilise : </p> <pre class="brush:php;toolbar:false;">+----+-------------------+------- ----+----------+-----------+-------------------------+ | ID tâche | terminé | ID parent | créé par | +----+-----------+-----------+--------------+- -------- ---+---------------------+ | 1 | Appartement propre | 0 | NULL 1 | | 2 | Nettoyer la salle de bain | 0 | 1 | 2022-03-24 00:47:33 | | 3 | Nettoyer la cuisine | 0 | 1 | 2022-03-24 00:47:33 | | 4 | Prendre une douche | 0 | 2 | 2022-03-24 00:47:33 | | 5 | Laver les toilettes | 0 | 2 | 2022-03-24 00:47:33 | | 6 | Nettoyage des vitres | 1 | 4 | 2022-03-24 00:47:33 | | 7 | Nettoyer les robinets | 0 | 4 | 2022-03-24 00:47:33 | | 8 | Nettoyer l'évier | 0 | 3 | 2022-03-24 00:47:33 | | 9 | Sortir la poubelle | 1 | 3 | 2022-03-24 00:47:33 | +----+-----------+-----------+--------------+- -------- ---+-----------+</pré> <p>Si je stocke cette base de données dans un tableau, je peux exécuter cette fonction : </p> <pre class="brush:php;toolbar:false;">function comp(tasks, taskId) { var task = tâches.find(task => task.id === taskId) var enfants = tâches.filter(t => t.parentId === taskId) task.children = children.map(child => comp(tasks, child.id)); tâche de retour }</pré> <p> pour imbriquer récursivement des sous-tâches dans la tâche principale. </p> <p>Le problème est que je ne comprends pas assez bien les fonctions asynchrones.</p> <p>Voici mes progrès jusqu'à présent : </p> <pre class="brush:php;toolbar:false;">async function comp(taskId) { // SELECT * FROM tâches OÙ id = taskId var task = wait con.promise().query('select * from tâches où id = ' + taskId) // SELECT * FROM tâches OÙ parentId = taskId var children = wait con.promise().query('select * from tâches où parentid = ' + taskId) tâche[0][0].children = children[0].map(child => { comp(enfant.id) }) console.log(tâche[0]) }</pré> <p>Mais cela renvoie une tâche avec des sous-tâches non définies : </p> <pre class="brush:php;toolbar:false;">[ { identifiant : 1, tâche : 'Nettoyer l'appartement', terminé : 0, ID parent : nul, créé par : 1, créé le : 2022-03-23T23:47:33.000Z, enfants : [ non défini, non défini ] } ]≪/pré> <p>En bref, ce que je veux, c'est ceci : </p> <pre class="brush:php;toolbar:false;">{ identifiant : 1, tâche : 'Nettoyer l'appartement', terminé : 0, ID parent : nul, créé par : 1, créé le : 2022-03-23T23:47:33.000Z, enfants: [ { identifiant : 2, tâche : « Nettoyer la salle de bain », terminé : 0, identifiant parent : 1, créé par : 1, créé le : 2022-03-23T23:47:33.000Z, enfants: [ { ID : 4, tâche : 'laver la douche', terminé : 0, parent-identifiant : 2, créé par : 1, créé le : 2022-03-23T23:47:33.000Z, enfants: [ ... ] }, { identifiant : 5, tâche : « laver les toilettes », terminé : 0, parent-identifiant : 2, créé par : 1, créé le : 2022-03-23T23:47:33.000Z, enfants: [ ... ] }, ] }, { identifiant : 3, tâche : « Nettoyer la cuisine », terminé : 0, identifiant parent : 1, créé par : 1, créé le : 2022-03-23T23:47:33.000Z, enfants: [ ... ] }, }</pré> <p>Des suggestions ? </p>
P粉729518806P粉729518806391 Il y a quelques jours488

répondre à tous(2)je répondrai

  • P粉970736384

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

    Vous attendez la fin de l'exécution des deux éléments attendus d'origine avant de démarrer le prochain appel récursif, puis d'imprimer sans attendre l'appel récursif lui-même.

    Tout d'abord, vous avez besoin de

    await comp(child.id);

    Mais il faut aussi attendre que chaque enfant ait fini de courir.

    Promise.all(array)

    attendra que chaque promesse du tableau que vous lui transmettez soit complétée, tandis que children[0].map(async () => {}) renverra un tableau de promesses. Continuez à attendre et ça devrait aller.

    répondre
    0
  • P粉596191963

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

    En fait, le seul problème avec votre code est que vous n'attendez pas que la promesse soit résolue lorsque toutes les promesses du tableau de la fonction asynchrone comp()的结果。 map()将返回一个Promise数组,你需要等待所有这些Promise,可以使用Promise.all()来实现。 Promise.all()返回一个Promise,当传递给Promise.all() ont été résolues. Si vous l'attendez, votre tableau children sera propagé comme prévu.

    C'est le code utilisant Promise.all(). Comme je n'ai pas actuellement de base de données appropriée, j'ai remplacé tous les appels asynchrones de votre base de données par un appel asynchrone à une fonction avec un délai artificiel afin que vous puissiez voir comment les appels sont attendus et si les résultats sont réellement attendus. .

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

    répondre
    0
  • Annulerrépondre