Właśnie skończyłem czytać specyfikację Promises / A + i natknąłem się na terminy microtask i macrotask: patrz http://promisesaplus.com/#notes
Nigdy wcześniej nie słyszałem o tych terminach, a teraz jestem ciekawy, jaka może być różnica?
Próbowałem już znaleźć jakieś informacje w sieci, ale znalazłem tylko ten post z archiwów w3.org (który nie wyjaśnia mi różnicy): http://lists.w3.org/Archives /Public/public-nextweb/2013Jul/0018.html
Dodatkowo znalazłem moduł npm o nazwie „macrotask”: https://www.npmjs.org/package/macrotask Ponownie nie jest wyjaśnione, na czym dokładnie polega różnica.
Wiem tylko, że ma to coś wspólnego z pętlą zdarzeń, jak opisano w https://html.spec.whatwg.org/multipage/webappapis.html#task-queue i https: //html.spec.whatwg .org / multipage / webappapis.html # perform-a-microtask-checkpoint
Wiem, że teoretycznie powinienem być w stanie samodzielnie wyodrębnić różnice, biorąc pod uwagę tę specyfikację WHATWG. Ale jestem pewien, że inni również mogliby skorzystać z krótkiego wyjaśnienia udzielonego przez eksperta.
źródło
while (task = todo.shift()) task();
Odpowiedzi:
Jedno obejście pętli zdarzeń spowoduje wykonanie dokładnie jednego zadania z kolejki makrozadań (kolejka ta jest nazywana po prostu kolejką zadań w specyfikacji WHATWG ). Po zakończeniu tego makrozadania wszystkie dostępne mikrozadania zostaną przetworzone, a mianowicie w ramach tego samego cyklu odejścia na drugi krąg . Podczas przetwarzania tych mikrozadań mogą one ustawiać w kolejce jeszcze więcej mikrozadań, z których wszystkie będą uruchamiane jedno po drugim, aż do wyczerpania kolejki mikrozadań.
Jakie są tego praktyczne konsekwencje?
Jeśli mikrozadanie rekurencyjnie kolejkuje inne mikrozadania, przetworzenie następnego makrozadania może zająć dużo czasu. Oznacza to, że możesz skończyć z zablokowanym interfejsem użytkownika lub niektórymi zakończonymi I / O bezczynnymi w aplikacji.
Jednak przynajmniej jeśli chodzi o funkcję process.nextTick Node.js (która kolejkuje mikrozadania ), istnieje wbudowana ochrona przed takim blokowaniem za pomocą process.maxTickDepth. Ta wartość jest ustawiona na wartość domyślną 1000, co ogranicza dalsze przetwarzanie mikrozadań po osiągnięciu tego limitu, co pozwala na przetworzenie następnego makrozadania )
Kiedy więc czego użyć?
Zasadniczo używaj mikrozadań gdy musisz wykonać coś asynchronicznie w sposób synchroniczny (tj. Gdy powiedziałbyś, że wykonaj to (mikro) zadanie w najbliższej przyszłości ). W przeciwnym razie trzymaj się makrozadań .
Przykłady
macrotasks: setTimeout , setInterval , setImmediate , requestAnimationFrame , I / O , renderowanie UI
mikrozadania: process.nextTick , Promises , queueMicrotask , MutationObserver
źródło
process.maxTickDepth
został usunięty bardzo dawno temu: github.com/nodejs/node/blob/…Podstawowe pojęcia w specyfikacji :
A model procesu pętli zdarzeń wygląda następująco:
gdy stos wywołań jest pusty, wykonaj następujące czynności:
uproszczony model procesu wygląda następująco:
coś do zapamiętania:
źródło
setImmediate()
to makro / zadanie iprocess.nextTick()
jest to mikro / zadanie.paint
zadaniami przeglądarki ? W jakiej kategorii by pasowali?requestAnimationFrame
)Myślę, że nie możemy omawiać pętli zdarzeń w oddzieleniu od stosu, więc:
JS ma trzy „stosy”:
A pętla zdarzeń działa w ten sposób:
Stos Mico nie zostanie dotknięty, jeśli stos nie jest pusty. Stos makr nie zostanie dotknięty, jeśli mikro stos nie jest pusty LUB nie wymaga wykonania.
Podsumowując: kolejka mikrozadań jest prawie taka sama jak kolejka makrozadań, ale te zadania (process.nextTick, Promises, Object.observe, MutationObserver) mają wyższy priorytet niż makrozadania.
Micro jest jak makro, ale ma wyższy priorytet.
Tutaj masz „ostateczny” kod do zrozumienia wszystkiego.
źródło