2017-12-30 14 views
1

Ich benutze eine API, die Kommentarobjekte zurückgibt, die Kommentare können Kinder haben, die auch Kommentarobjekte sind.Rekursive Funktion mit Promises

Ich versuche, den gesamten Kommentar-Thread mit Rekursion abrufen, aber es funktioniert nicht, sobald ein Kommentar kein Kind hat die Funktion endet früh und das zurückgegebene Ergebnis enthält nicht den gesamten Kommentar-Thread.

Wie kann ich die Funktion so ändern, dass die Lösung auftritt, nachdem alle Kommentare überprüft wurden, um keine Kinder zu haben.

Beispiel eines Kommentars Objekt thats, durch die api zurück

{ 
    "id": 16020433, 
    "kids": [ 
    16021684, 
    16021721, 
    16021659 
    ], 
    "title": "Why isn't literally every train automated?", 
    "type": "story" 
} 

Hier ist mein Code:

function getCommentsWrapper(id) { 
    let comments = []; 
    return new Promise((resolve, reject) => { 
    function recurseComments(id) { 
     let url = `https://hacker-news.firebaseio.com/v0/item/${id}.json`; 
     let comment = {}; 
     fetch(url) 
     .then(response => response.json()) 
     .then(cmt => { 
      comment = cmt 
      comments.push(comment); 
      if (comment.kids) { 
      comment.kids.forEach(id => recurseComments(id)); 
      } else { 
      resolve(comments) 
      } 
     }) 
    } 

    recurseComments(id); 
    }) 



    // call the function with 
    getCommentsWrapper("16033496") 
    .then(result => console.log(result)); 

Antwort

0

Sie können den Anruf Zählung Technik verwenden, wie in dem folgenden Code. Oder Sie können eine Bibliothek wie Bluebrid verwenden. Ich denke, sie haben viele Möglichkeiten.

Ich denke auch Promise.all kann die erforderlichen tun, aber in meiner bisherigen Erfahrung, neue Versprechen Promise.all hinzufügen, während die Versprechen Array behandelt wird, war nicht zuverlässig.

function getCommentsWrapper(id) { 

    var promises = []; 
    let count = 0; 

    let futureValue = new Promise((resolveAll, rejectAll)=>{ 
     let comments = []; 
     let call = (id) => { 
     count++; 
     new Promise((resolve, reject) => { 
      let url = `https://hacker-news.firebaseio.com/v0/item/${id}.json`; 
      let comment = {}; 
      fetch(url) 
      .then(response => response.json()) 
      .then(cmt => { 
       comment = cmt 
       comments.push(comment); 
       if (comment.kids) { 
       comment.kids.forEach(id => call(id)); 
       } 

       resolve(); 
       count--; 
       if(count < 1){ 
       resolveAll(comments); 
       } 
      }) 
     }); 
     }; 

     call(id); 
    }); 
    return futureValue; 
} 


// call the function with 
getCommentsWrapper("16033496") 
    .then(result => console.log(result)); 
+0

Danke das Hinzufügen der count-Variable, um zu verfolgen, wie oft die verschachtelten Kommentare gut funktionieren. Was ist der Grund für das Erstellen des zusätzlichen Versprechens, das Promise, das den Abruf durchführt, zu umschlingen? –

+0

So können Sie das Muster, das Sie in Ihrem Code haben, wie in getCommentsWrapper verfolgen. Andernfalls müssen Sie einen Rückruf erstellen. – orabis