Gdybym potrzebował wywołać 3 http API w kolejności sekwencyjnej, jaka byłaby lepsza alternatywa dla następującego kodu:
http.get({ host: 'www.example.com', path: '/api_1.php' }, function(res) {
res.on('data', function(d) {
http.get({ host: 'www.example.com', path: '/api_2.php' }, function(res) {
res.on('data', function(d) {
http.get({ host: 'www.example.com', path: '/api_3.php' }, function(res) {
res.on('data', function(d) {
});
});
}
});
});
}
});
});
}
node.js
synchronization
Howard
źródło
źródło
sync-request
bibliotece, która jest dobrą odpowiedzią na tytuł tego pytania, ale nie jest odpowiedzią na to, co sugeruje kod pytania. Poniższa odpowiedź dotycząca obietnic jest lepszą odpowiedzią na to pytanie. Co miałeś na myśli?Odpowiedzi:
Korzystanie z odroczonych, takich jak
Futures
.Jeśli chcesz przekazać zakres, po prostu zrób coś takiego
źródło
Podoba mi się również rozwiązanie Raynos, ale wolę inną bibliotekę sterowania przepływem.
https://github.com/caolan/async
W zależności od tego, czy potrzebujesz wyników w każdej kolejnej funkcji, użyłbym serii, równoległości lub wodospadu.
Serie, gdy muszą być wykonywane seryjnie, ale niekoniecznie potrzebujesz wyników w każdym kolejnym wywołaniu funkcji.
Równoległe, jeśli mogą być wykonywane równolegle, nie potrzebujesz wyników z każdej funkcji równoległej i potrzebujesz wywołania zwrotnego po zakończeniu wszystkich.
Wodospad, jeśli chcesz zmienić wyniki w każdej funkcji i przejść do następnej
źródło
Możesz to zrobić za pomocą mojej biblioteki Common Node :
źródło
require(...).HttpClient is not a constructor
sync-request
Zdecydowanie najłatwiejszym, jaki znalazłem i użyłem, jest żądanie synchronizacji i obsługuje zarówno węzeł, jak i przeglądarkę!
To wszystko, bez szalonej konfiguracji, bez skomplikowanych instalacji lib, chociaż ma rezerwę lib. Po prostu działa. Wypróbowałem tutaj inne przykłady i byłem zaskoczony, gdy było dużo dodatkowej konfiguracji lub instalacje nie działały!
Uwagi:
Przykład, którego używa żądanie synchronizacji, nie działa dobrze, gdy używasz
res.getBody()
, wszystko, co robi get body, to zaakceptowanie kodowania i przekonwertowanie danych odpowiedzi. Po prostu zrób tores.body.toString(encoding)
.źródło
Użyłbym funkcji rekurencyjnej z listą apis
edycja: żądanie wersji
edycja: wersja żądania / asynchroniczna
źródło
Wygląda na to, że rozwiązania tego problemu nigdy się nie kończą, oto jeszcze jedno :)
http://alexeypetrushin.github.com/synchronize
źródło
Inną możliwością jest skonfigurowanie wywołania zwrotnego, które śledzi ukończone zadania:
Następnie po prostu przypisz identyfikator do każdego z nich i możesz ustawić wymagania, dla których zadania muszą zostać zakończone przed zamknięciem połączenia.
Okej, to nie jest ładne. To tylko inny sposób wykonywania połączeń sekwencyjnych. Szkoda, że NodeJS nie zapewnia najbardziej podstawowych wywołań synchronicznych. Ale rozumiem, czym kusi asynchroniczność.
źródło
użyj sekwencji.
sudo npm zainstaluj sekwencję
lub
https://github.com/AndyShin/sequenty
bardzo prosty.
możesz również użyć pętli takiej jak ta:
źródło
Korzystanie z biblioteki żądań może pomóc zminimalizować problem:
Ale dla maksymalnej niesamowitości powinieneś wypróbować jakąś bibliotekę kontroli przepływu, taką jak Step - pozwoli ci to również na zrównoleglenie żądań, zakładając, że jest to akceptowalne:
źródło
Od 2018 roku i używając modułów ES6 i Promises, możemy napisać taką funkcję:
a potem w innym module
Kod musi być wykonywany w kontekście asynchronicznym (przy użyciu
async
słowa kluczowego)źródło
Istnieje wiele bibliotek kontroli przepływu - lubię conseq (... ponieważ to napisałem). Ponadto
on('data')
może uruchamiać się kilka razy, więc użyj biblioteki opakowującej REST, takiej jak restler .źródło
Na to dobrze odpowiedział Raynos. Jednak od czasu opublikowania odpowiedzi zaszły zmiany w bibliotece sekwencji.
Aby sekwencja działała, kliknij ten link: https://github.com/FuturesJS/sequence/tree/9daf0000289954b85c0925119821752fbfb3521e .
Oto, jak możesz to uruchomić po
npm install sequence
:źródło
Oto moja wersja @ andy-shin sekwencyjnie z argumentami w tablicy zamiast indeksu:
źródło
...4 lata później...
Oto oryginalne rozwiązanie z frameworkiem Danf (nie potrzebujesz żadnego kodu do tego typu rzeczy, tylko trochę konfiguracji):
Jeśli chcesz być jeszcze krótszy, możesz skorzystać z procesu windykacji:
Zapoznaj się z omówieniem struktury, aby uzyskać więcej informacji.
źródło
Wylądowałem tutaj, ponieważ musiałem ograniczyć http.request (~ 10k zapytań agregujących do elastycznego wyszukiwania w celu zbudowania raportu analitycznego). Następujące po prostu zakrztusiły moją maszynę.
Moje adresy URL są bardzo proste, więc może to nie mieć zastosowania do pierwotnego pytania, ale myślę, że jest to zarówno potencjalnie możliwe, jak i warte napisania tutaj dla czytelników, którzy trafiają tutaj z problemami podobnymi do moich i chcą trywialnego rozwiązania JavaScript bez biblioteki.
Moja praca nie była zależna od zamówienia, a moim pierwszym podejściem do tego było zawinięcie go w skrypt powłoki, aby go podzielić (ponieważ jestem nowy w JavaScript). To było funkcjonalne, ale niezadowalające. Ostatecznie moje rozwiązanie JavaScript polegało na wykonaniu następujących czynności:
Wygląda na to, że wzajemna rekurencja między zbieraniem i get_top . Nie jestem pewien, czy to działa, ponieważ system jest asynchroniczny, a funkcja collect kończy się wywołaniem zwrotnym zapisanym dla zdarzenia o godzinie on. ('End' .
Myślę, że wystarczy odnosić się do pierwotnego pytania. Jeśli, tak jak w moim scenariuszu, sekwencja / zestaw jest znana, wszystkie adresy URL / klucze można umieścić na stosie w jednym kroku. Jeśli są obliczane na bieżąco , funkcja on ('end' może umieścić następny adres URL na stosie tuż przed get_top () . Jeśli już, wynik ma mniej zagnieżdżenia i może być łatwiejszy do refaktoryzacji podczas wywoływania interfejsu API zmiany.
Zdaję sobie sprawę, że jest to równoważne z prostą rekurencyjną wersją @ generalhenry powyżej (więc zagłosowałem za tym!)
źródło
Super żądanie
To kolejny moduł synchroniczny oparty na żądaniach i korzystający z obietnic. Super prosty w użyciu, działa dobrze z testami mokki.
npm install super-request
źródło
Ten kod może być użyty do wykonania tablicy obietnic synchronicznie i sekwencyjnie, po czym można wykonać swój końcowy kod w
.then()
wywołaniu.źródło
Właściwie dostałem dokładnie to, czego ty (i ja) chciałeś, bez użycia czekania, obietnic lub włączeń jakiejkolwiek (zewnętrznej) biblioteki (z wyjątkiem naszej własnej).
Oto jak to zrobić:
Zamierzamy stworzyć moduł C ++, który będzie współpracował z node.js, a ta funkcja modułu C ++ wykona żądanie HTTP i zwróci dane jako ciąg znaków, a możesz użyć tego bezpośrednio, wykonując:
CZY JESTEŚ GOTOWY, aby zacząć?
Krok 1: utwórz nowy folder w innym miejscu na swoim komputerze, używamy tego folderu tylko do budowania pliku module.node (skompilowanego z C ++), możesz go przenieść później.
W nowym folderze (umieściłem mój w mynewFolder / src w celu uporządkowania):
następnie
teraz stwórz 2 nowe pliki: 1, nazwane coś.cpp i umieść w nim ten kod (lub zmodyfikuj, jeśli chcesz):
Teraz utwórz nowy plik w tym samym katalogu o nazwie
something.gyp
i umieść w nim (coś podobnego):Teraz w pliku package.json dodaj:
"gypfile": true,
Teraz: w konsoli
node-gyp rebuild
Jeśli przejdzie przez całą komendę i na końcu powie "ok" bez błędów, jesteś (prawie) gotowy, jeśli nie, zostaw komentarz.
Ale jeśli to zadziała, przejdź do build / Release / cobypp.node (lub cokolwiek, o co ci chodzi), skopiuj go do głównego folderu node.js, a następnie do node.js:
źródło