2015-12-18 15 views
8

Proszę wybaczyć mi, że powtarzam już bardzo zadane pytanie, ale wszystko, co do tej pory widziałem, nie wydaje mi się rekurencyjne ani nie odwzorowuje na to, co robimy, i temat obietnic i odroczeń wydaje mi się bardzo złożony.Jak poprawnie zakodować rekursywną obietnicę jquery

Mam "drzewo tematów", które jest budowane asynchronicznie, gdy użytkownik rozwija węzły. Ten temat jest zbudowany przy użyciu punktu końcowego API, który zwraca elementy podrzędne węzła po kliknięciu przycisku (+) w węźle drzewa tematów.

Gdy użytkownik kliknie przycisk staram się rekurencyjnie załadować elementy temat drzew metodą, która wygląda tak:

function getAssociatedTopics(){ 
    $.get('/topics/curriculum-associations', {guids: [...]}) 
    .then(function(data){ 

     //Process the topic information here 
     var topicId = /* some processing */; 

     //Get ancestors of each topic returned 
     $.get('/topics/getAncestors', {of: topicId}) 
     .then(function(data){ 

      //Process the topic information here 
      var topicId = /* some processing */; 

      //Get ancestors of each topic returned 
      //Rinse repeat as long as we find children of each topic found 


     }); 

    }).then(function(){ 

     //Expand the nodes 
     //Select the nodes 

    }); 
} 

Więc to powinno wyglądać, ale mam wszystko stracone czytanie dokumentacja, aby upewnić się, że moje rzeczy są wykonywane we właściwej kolejności ... Wielkim problemem, jaki mamy teraz z tą strukturą, jest to, że wszystkie moje węzły ładują się w równoczesny sposób, a następnie usuwają wybrane węzły, otwierają i zamykają węzły w dowolnym momencie i wybór kończy się bardzo niechlujnie.

Nie chcę dogłębnie wyjaśnić obietnic, ani nie chcę pełnego rozwiązania, ale ogólny pomysł, jak to osiągnąć.

+0

Chcesz rozwinąć poddrzewo węzła? A może tylko pierwsze dzieci? – MinusFour

+0

Mówisz "kiedy użytkownik kliknie przycisk", czy ten przycisk to przycisk '(+)' w węźle drzewa tematów, czy jakiś inny przycisk? Ponieważ * mówisz * masz "punkt końcowy API, który zwraca węzły węzła", ale nie pokazałeś niczego, co wyraźnie to jeszcze robi (chyba, że ​​to robi '/ topics/curriculum-association'). –

+2

Ponadto, kod mówi * Uzyskaj przodków każdego zwróconego tematu *, co prowadzi mnie do przekonania, że ​​istnieje pętla, której nie widzimy. Pętla, która może bardzo dobrze określić poprawność odpowiedzi ... –

Odpowiedz

1

Pierwsza rzecz, złożoność pobierania potrzebnych informacji powinna być obsługiwana na serwerze, a nie na kliencie. Wykonywanie setek żądań HTTP od klienta jest katastrofą wydajności, która czeka na realizację.

Teraz jak chcesz to zrobić, dwa ważne fakty:

  • Promises pracować przy użyciu wartości powrotną. $.get zwraca obietnicę wartości - dlatego możesz ją wyłączyć, ale możesz też zwrócić ją na zewnątrz.
  • Jeśli zwrócisz obietnicę od osoby obsługującej then, obietnica wróci z samego then sama będzie czekać na wewnętrzną obietnicę do rozstrzygnięcia w pierwszej kolejności.

Oto przykład ilustrujący dwa punkty:

$.get("/api").then(function(data) { 
    return $.get("/api2/" + data.id); 
}).then(function(data2) { 
    // because of point #1, we get the data of the inner call here. 
}); 

Teraz do rzeczywistego problemu:

function getAssociatedTopics(guids) { 
    // note the `return` here so it can be chained from outside 
    return $.get('/topics/curriculum-associations', {guids: guids}) 
    .then(function(data){ 
     var topicId = someProcessing(data); 
     // note we return here. I assume this get returns guids. 
     return $.get('/topics/getAncestors', {of: topicId}) 
    }).then(function (guids) { // this anonymous function can be inlined 
     if(guids.length === 0) return; // stop condition 
     return getAssociatedTopics(guids); // note the recursive call, remember point #2. 
    }); 
} 
getAssociatedTopics(initial).then(function(){ 
    // all done 
}); 

Jeśli potrzebujesz wyniki wszystkich połączeń, można go łańcuch off, lub możesz popchnąć do tablicy zmiennych zamknięcia wewnątrz tego przed ostatnim i uzyskać do niego dostęp w całej zrobionej procedurze obsługi.

Powiązane problemy