2013-05-20 8 views
10

Pracuję nad a JavaScript library, która zapewnia, między innymi, funkcję mapowania/zmniejszania sekwencji, które mogą być iterowane asynchronicznie.Czy należy użyć metody process.nextTick lub setImmediate w przypadku asynchronicznej iteracji?

A helpful soul on GitHub zasugerował, że dla Node.js powinienem użyć process.nextTick, aby asynchroniczne iteracje tak szybko jak to możliwe. (Biblioteka obecnie używa setTimeout we wszystkich środowiskach, co rozumiem jest nieoptymalna.) Jestem dość niedoświadczony, jeśli chodzi o Węzeł, więc czytałem o tym, jak działa ta metoda i nie jest dla mnie jasne, czy to jest dobry wybór, czy nie.

Według the answer to another question on SO, wydaje się, że będzie to prawdopodobnie więcej sensu używać setImmediate w tym przypadku jako nextTick widocznie skacze naprzód w oczekiwaniu wydarzeń I/O, które wydaje zły na mnie.

To wydaje się być potwierdzone przez niektórych uwagach the official Node v0.10.0 announcment:

W v0.10, nextTick teleskopowe są prowadzone bezpośrednio po każdym połączeniu z C++ w JavaScripcie. Oznacza to, że jeśli twój kod JavaScript wywoła process.nextTick, wywołanie zwrotne zostanie uruchomione, gdy kod zostanie uruchomiony , ale przed powróci do pętli zdarzeń.

Tak, mam rację, a powtarzanie sekwencji asynchronicznie powinno odbywać się przy pomocy setImmediate? Czy może lepszym wyborem byłby tutaj nextTick? (W każdym razie jasne wyjaśnienie dlaczego będą mile widziane.)

+0

Dlaczego dokładnie potrzebujesz "asynchronicznej iteracji"? –

+0

Załóżmy, że masz długą listę elementów danych, które wymagają pewnego rodzaju kosztownego przetwarzania, po pozycji. użycie 'nextTick' /' setImmediate' pozwoli na uruchomienie innego kodu pomiędzy każdym etapem przetwarzania, a tym samym potencjalnie zachowanie możliwości np. odpowiedź na żądanie HTTP lub, powiedzmy, interakcja użytkownika z GUI. – flow

Odpowiedz

10

Kilka uwag:

bym najpierw zrobić poważne odniesienia do jakiego stopnia setImmediate jest wolniejszy niż process.nextTick. Jeśli nie jest to (dużo) wolniejsze, od razu wybrałbym setImmediate, ponieważ nie zagłodzi pętli zdarzeń.

W węźle 0.10 istnieje sztywny limit (1000, zobacz node.js docs), ile razy można rekurencyjnie wywoływać nextTick, więc należy temu zapobiec w każdym przypadku. Musisz wybrać strategię przed iteracją lub móc zmienić strategię podczas iteracji (podczas sprawdzania aktualnej liczby iteracji).

Jeśli wybierzesz process.nextTick ze względu na wydajność, możesz ustawić konfigurowalny sztywny limit liczby powtórzeń, ile razy zrobiłoby to process.nextTick z rzędu, a następnie przełączyć na setImmediate. Nie mam doświadczenia z poważnymi obciążeniami pracy dla nodejów, ale myślę, że ludzie nie polubią tego, jeśli twoja biblioteka wykona swój ruch we/wy.

SetImmediate z pewnością byłby najbezpieczniejszy, w sumie.

chodzi o przeglądarce: nie badali swoją bibliotekę, ale ponieważ w rzeczywistości pochodzące z setTimeout może być wspomagane poznawania nowej rasy technik opóźnienia poprzez window.postMessage, a co nie. Jest ładna i mała biblioteka o nazwie next-tick (ale z inną semantyką niż węzeł next-tick!) I jest tam cross-browser shim for setImmediate, która jest nieco cięższa, ponieważ 1) musi implementować specyfikację setImmediate (w tym możliwość anulowania zaplanowanych zadań) i 2) ma znacznie szerszą kompatybilność przeglądarki.

Sprawdź to async sorting demo, porównując setImmediate (shim) do setTimeout.

+1

Nawet jeśli 'nextTick' był w pewnym sensie znacznie szybszy niż' setImmediate', myślę, że byłoby mu lepiej po prostu wykonać więcej pracy przed ponownym wywołaniem 'setImmediate'. W końcu nie ma sensu wykonywać kodu źródłowego, jeśli i tak wszystko się zablokuje. – Hristo

+1

@ ChristoDachev: Dobra uwaga. Ale z jego pytaniem w obecnym stanie, nie jest dokładnie jasne, dlaczego chce "asynchronicznie iterować". Dzielenie pracy na partie, które są wykonywane synchronicznie, utraciłoby część asynchroniczności. Jeśli wszystko, czego potrzeba, to asynchroniczny interfejs dla operacji wsadowej, wystarczyłby pojedynczy "setImmediate" dla całej ilości pracy, czyniąc różnice prędkości nieistotnymi. Zapytam. –

+0

nie, zobacz mój komentarz powyżej. – flow

Powiązane problemy