Druga próba odpowiedzi, w której staram się wyjaśnić:
Po pierwsze, niezbędne informacje z pliku README RSVP :
Naprawdę niesamowita część pojawia się, gdy zwracasz obietnicę z pierwszego modułu obsługi ... Pozwala to na spłaszczenie zagnieżdżonych wywołań zwrotnych i jest główną cechą obietnic, która zapobiega „dryfowaniu w prawo” w programach z dużą ilością kodu asynchronicznego.
Dokładnie w ten sposób składasz obietnice sekwencyjnie, zwracając późniejszą obietnicę z then
obietnicy, która powinna się zakończyć przed nią.
Warto pomyśleć o takim zestawie obietnic jak o drzewie, w którym gałęzie reprezentują procesy sekwencyjne, a liście - procesy współbieżne.
Proces tworzenia takiego drzewa obietnic jest analogiczny do bardzo częstego zadania budowania innych rodzajów drzew: utrzymuj wskaźnik lub odniesienie do miejsca w drzewie, w którym obecnie dodajesz gałęzie, i iteracyjnie dodawaj elementy.
Jak zauważył @Esailija w swojej odpowiedzi, jeśli masz tablicę funkcji zwracających obietnice, które nie przyjmują argumentów, możesz użyć, reduce
aby starannie zbudować drzewo. Jeśli kiedykolwiek wdrożyłeś redukcję dla siebie, zrozumiesz, że to, co redukuje robi za kulisami w odpowiedzi @ Esailija, to utrzymywanie odniesienia do bieżącej obietnicy ( cur
) i zwracanie każdej obietnicy następnejthen
.
Jeśli NIE masz ładnej tablicy jednorodnych (w odniesieniu do argumentów, które przyjmują / zwracają) obietnic zwracających funkcje lub jeśli potrzebujesz bardziej skomplikowanej struktury niż prosta sekwencja liniowa, możesz samodzielnie skonstruować drzewo obietnic, zachowując odniesienie do pozycji w drzewie obietnic, w której chcesz dodać nowe obietnice:
var root_promise = current_promise = Ember.Deferred.create();
current_promise = current_promise.then(function(){
return
});
current_promise = current_promise.then(function(){
return
});
root_promise.resolve();
Można tworzyć kombinacje procesów współbieżnych i sekwencyjnych, używając RSVP.all do dodawania wielu „liści” do „gałęzi” obietnicy. Moja odpowiedź, na którą przyznaję, że jest zbyt skomplikowana, jest tego przykładem.
Możesz również użyć Ember.run.scheduleOnce ('afterRender'), aby upewnić się, że coś, co zostało zrobione w jednej obietnicy, zostanie renderowane przed uruchomieniem następnej obietnicy - moja odpowiedź, która nie została uznana za zbyt skomplikowaną, również pokazuje tego przykład.