2017-11-21 1 views
2

Also ich muss das Ergebnis eines Versprechens verwenden, um eine weitere FFTCH-Anfrage zu machen, ich arbeite mit dem Rest API für WordPress, und ich brauche die ID der Unterkategorien im Post-Objekt, um diesen Kategorienamen abzurufen und baue zwei Arrays, eins mit den Posts und eins mit Kategorien, die zur Verfügung stehen. Hier ist meine FunktionJavascript. Warten auf verschachtelte Fetch Versprechen

function fetchAccordionData() 
{ 
    const id = document.querySelector('.acc').getAttribute('data-id'), 
      wpRestAPI = '/wp-json/wp/v2/'; 
    return fetch(wpRestAPI + 'posts?per_page=100&categories=' + id) 
     .then((resp) => resp.json()) 
     .then((data) => 
     { 
      let curId = [], subCatList = []; 
      data.map((post) => 
      { 
       let catList = post.categories.filter((c) => c !== parseInt(id)); 
       fetch(wpRestAPI + 'categories/' + catList[0]) 
        .then((r) => r.json()) 
        .then((cat) => 
        { 
         if(!curId.includes(cat.id)) subCatList.push({id: cat.id, name: cat.name}); 
         curId.push(cat.id); 
        }); 
      }); 
      return {'subCatList':subCatList, 'posts':data} 
    }); 
} 

Nun, wenn ich die Funktion der subCatList Array isn `t bereit, rufen Sie noch:

fetchAccordionData().then((data) => 
    { 
     console.log(data.subCatList, data.posts); 
     for(let cat of data.subCatList) 
     { 
      console.log(cat); 
     } 
    }); 

Also, wie kann ich wissen, wenn das Versprechen der zweiten ist so gelöst Abruf Ich kann die Daten verwenden?

+1

Sie suchen nach 'Promise.all()'. – SLaks

+0

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all – Andreas

Antwort

1

Sie müssen alle Ihre Versprechen in einem Array ablegen und Promise.all verwenden, um auf alle diese Versprechen zu warten, bevor Sie auf subCatList zugreifen.

Ihr modifizierte Code würde wie so aussehen:

function fetchAccordionData() { 

    const id = document.querySelector('.acc').getAttribute('data-id'), 
      wpRestAPI = '/wp-json/wp/v2/'; 

    return fetch(wpRestAPI + 'posts?per_page=100&categories=' + id) 
     .then((resp) => resp.json()) 
     .then((data) => { 

      let curId = [], subCatList = []; 

      // promises is an array of promises 
      let promises = data.map((post) => { 

       let catList = post.categories.filter((c) => c !== parseInt(id)); 

       // return a promise on each iteration 
       return fetch(wpRestAPI + 'categories/' + catList[0]) 
        .then((r) => r.json()) 
        .then((cat) => 
        { 
         if(!curId.includes(cat.id)) subCatList.push({id: cat.id, name: cat.name}); 
         curId.push(cat.id); 
        }); 
      }); 

      return Promise.all(promises) 
       .then(() => ({'subCatList':subCatList, 'posts':data})); 
     }); 
} 

Beachten Sie, dass der letzte Schritt gibt das Objekt {'subCatList': subCatList, 'post': data}nur nach jedem Versprechen in promises abgeklungen ist. Auf diese Weise können Sie sicher sein, dass die Versprechungen in dem Array abgeschlossen sind, push in subCatList zu machen.

Es ist auch erwähnenswert, dass die Schnittstelle von fetchAccordionData blieb genau das gleiche, so sollten Sie es verwenden können, wie Sie in Ihrem ursprünglichen Beispiel tat

fetchAccordionData().then((data) => { 

    console.log(data.subCatList, data.posts); 

    for(let cat of data.subCatList) { 
     console.log(cat); 
    } 
}); 
+0

Awesome, danke Mann! es gibt nur ein kleines Problem mit der Rückgabe des Versprechens.alles, es weiß nicht, dass ich ein Objekt will und kann die Currly Braces nicht richtig lesen, also musste ich das Objekt separat setzen. let r = {'subCatList' : subCatList, 'Beiträge': Daten}; zurück Promise.all (Versprechen) .then (() => r); ' – penHolder

+1

Woops! Das funktioniert, aber Sie möchten vielleicht die bearbeitete Version oben versuchen, wo der Ausdruck lautet: '.then (() => ({'subCatList': subCatList, 'posts: data})); das Objekt in Klammern, so dass ein Objekt zurückgegeben wird. Wenn 'subCatList' ein primitives Element wäre (d. H. Eine' Zeichenkette'), müssten Sie das Objekt definitiv nach 'Promise.all' erstellen oder Ihr Objekt würde einen veralteten Wert für' subCatList' enthalten. –

0

Es sieht aus wie

return {'subCatList':subCatList, 'posts':data} 

ist außerhalb des Teils Ihrer Funktion, die Kategorien aus dem Rest API bekommt:

data.map((post) => 
      { 
       let catList = post.categories.filter((c) => c !== parseInt(id)); 
       fetch(wpRestAPI + 'categories/' + catList[0]) 
        .then((r) => r.json()) 
        .then((cat) => 
        { 
         if(!curId.includes(cat.id)) subCatList.push({id: cat.id, name: cat.name}); 
         curId.push(cat.id); 
        }); 
      }); 

, sodass Ihre Funktion sie zurückgibt, bevor sie die Kategoriendaten aus der API abrufen kann. Wenn Sie Ihre Return-Anweisung nach der letzten then-Anweisung setzen, sollte sie die gesuchten Daten zurückgeben:

data.map((post) => 
      { 
       let catList = post.categories.filter((c) => c !== parseInt(id)); 
       fetch(wpRestAPI + 'categories/' + catList[0]) 
        .then((r) => r.json()) 
        .then((cat) => 
        { 
         if(!curId.includes(cat.id)) subCatList.push({id: cat.id, name: cat.name}); 
         curId.push(cat.id); 
         return {'subCatList':subCatList, 'posts':data} 
        }); 
      }); 
Verwandte Themen