Mam strukturę podobną do tablicy, która uwidacznia metody asynchroniczne. Metoda async wywołuje zwracające struktury tablicowe, które z kolei ujawniają więcej metod asynchronicznych. Tworzę kolejny obiekt JSON do przechowywania wartości uzyskanych z tej struktury, dlatego muszę uważać na śledzenie odwołań w wywołaniach zwrotnych.
Zakodowałem rozwiązanie brutalnej siły, ale chciałbym nauczyć się bardziej idiomatycznego lub czystego rozwiązania.
- Wzór powinien być powtarzalny dla n poziomów zagnieżdżenia.
- Muszę użyć promise.all lub innej podobnej techniki, aby określić, kiedy należy rozwiązać procedurę obejmującą.
- Nie każdy element będzie koniecznie wymagał wywołania asynchronicznego. Tak więc w zagnieżdżonej obietnicy.all nie mogę po prostu przypisywać elementów do mojej tablicy JSON na podstawie indeksu. Niemniej jednak muszę użyć czegoś takiego jak obietnica.all w zagnieżdżonym forEach, aby upewnić się, że wszystkie przypisania właściwości zostały dokonane przed rozwiązaniem procedury zamykającej.
- Używam bluebird promise lib, ale nie jest to wymagane
Oto fragment kodu -
var jsonItems = [];
items.forEach(function(item){
var jsonItem = {};
jsonItem.name = item.name;
item.getThings().then(function(things){
// or Promise.all(allItemGetThingCalls, function(things){
things.forEach(function(thing, index){
jsonItems[index].thingName = thing.name;
if(thing.type === 'file'){
thing.getFile().then(function(file){ //or promise.all?
jsonItems[index].filesize = file.getSize();
javascript
node.js
asynchronous
promise
user3205931
źródło
źródło
Promise.map
(równoległe) iPromise.each
(sekwencyjnego) W tym przypadku, również uwagaPromise.defer
jest przestarzała - kod w moich pokazów Odpowiedź Jak unikać jej przez powrocie obietnic. Obietnice dotyczą zwracanych wartości.Odpowiedzi:
Jest to całkiem proste dzięki kilku prostym zasadom:
then
, zwróć ją - żadna obietnica, której nie zwrócisz, nie będzie czekana na zewnątrz..all
one - w ten sposób czekają na wszystkie obietnice i żaden błąd z nich nie jest uciszany.then
, zazwyczaj możesz powrócić na środek -then
łańcuchy są zwykle na głębokości co najwyżej 1 poziomu.I kilka wskazówek:
.map
niż zfor/push
- jeśli odwzorowujesz wartości za pomocą funkcji,map
pozwala zwięźle wyrazić koncepcję stosowania działań jeden po drugim i agregowania wyników.Promise.all
niż wykonywać czynności jedna po drugiej - każda z nich czeka przed następną.Ok, więc zaczynajmy:
źródło
Oto prosty przykład użycia funkcji redukuj. Działa seryjnie, utrzymuje kolejność reklam i nie wymaga Bluebird.
I użyj tego w ten sposób:
Okazało się, że przydatne jest wysyłanie opcjonalnego kontekstu do pętli. Kontekst jest opcjonalny i wspólny dla wszystkich iteracji.
Twoja funkcja obietnicy wyglądałaby następująco:
źródło
Miałem tę samą sytuację. Rozwiązałem za pomocą dwóch Promise.All ().
Myślę, że było to naprawdę dobre rozwiązanie, więc opublikowałem je na npm: https://www.npmjs.com/package/promise-foreach
Myślę, że twój kod będzie mniej więcej taki
źródło
Aby dodać do przedstawionego rozwiązania, w moim przypadku chciałem pobrać wiele danych z Firebase do listy produktów. Oto jak to zrobiłem:
źródło