2011-11-08 15 views
11

Czy można uniknąć przepełnienia stosu w javascriptie, używając metody setTimeout do wywoływania funkcji zamiast wywoływania jej bezpośrednio? Moje rozumienie setTimeout polega na tym, że powinien on uruchomić nowy callstack. Kiedy patrzę na stację wywoławczą zarówno chrome, jak i IE, wydaje się, że wywołania setTimeout czekają na wywołanie funkcji.Czy wywołanie setTimeout czyści stację wywoławczą?

Czy jest to tylko właściwość debuggera, czy też moje rozumienie jest wadliwe?

EDIT

Podczas odpowiedzi podane poniżej są poprawne, rzeczywisty problem miałem było związane z faktem, że dzwoni setTimeout (aFunction(), 10), który oceniającego aFunction natychmiast ze względu na nawiasy. This question posortował mnie.

+0

Funkcja przekazana do 'setTimeout' nie można powoływać się przed funkcji, która wywołała' setTimeout' zwrócone. Więc tak, ta funkcja uruchamia nowy callstack. –

Odpowiedz

12

Mogę potwierdzić, że stos został wyczyszczony.

Rozważmy następujący scenariusz:

function a() { 
    b(); 
} 

function b() { 
    c(); 
} 

function c() { 
    debugger; 
    setTimeout(d, 1000); 
} 

function d() { 
    debugger; 
} 

a(); 

więc istnieją dwie wartości graniczne - jedno na początku funkcji c, a jeden na początku funkcji d.

stos w pierwszym zerwaniu:

  • c()
  • b()
  • ()

stosu na drugi przerwania:

  • d()

żywo demo:http://jsfiddle.net/nbf4n/1/

+0

dzięki za wskazanie mi w dobrym kierunku, udało mi się rozwiązać w oparciu o twoją odpowiedź, jednak mam inne pytanie zobacz http://stackoverflow.com/questions/8058996/why-does-calling-settimeout- with-parenthesis- not-start-a-new-callstack –

+0

Jeśli ten facet ma rację, w jaki sposób twoja odpowiedź może być właściwą odpowiedzią? Ponieważ ten facet mówi, że zawsze przesyła callback do kolejki wywołania zwrotnego, a nie do stosu, więc jeśli w stosie wywoławczym nadal działa polecenie synchroniczne, LUB inne rzeczy w stosie musi poczekać nawet więcej niż określone milisekundy . Więc nie zawsze jest to 1: 1. To może się zdarzyć: hej dałem ci 5 sekundowe opóźnienie, dlaczego wróciłeś w 7? ponieważ callback musiał poczekać trochę więcej. https://youtu.be/8aGhZQkoFbQ?t=782 – PositiveGuy

+0

Opóźnienie, które określasz za pomocą drugiego argumentu 'setTimeout', nie gwarantuje, że wywołanie zwrotne zostanie wywołane w tym konkretnym momencie, true; ale moja odpowiedź nie mówi, że tak. –

4

Inwokacje asynchroniczne, takie jak te z setTimeout, rzeczywiście generują nowy moduł wywoławczy.

Nie jest do końca jasne, co opisujesz, mówiąc: "Kiedy patrzę na stację wywoławczą zarówno Chrome, jak i IE, wydaje się, że wywołania setTimeout czekają na wywołanie funkcji." Ale jedną rzeczą, którą możesz zrobić, to umieścić punkt przerwania w funkcji wywoływanej przez setTimeout i sprawdzić, czy ten moduł jest pusty.

+0

Czy wiesz, dlaczego wciąż mogę zobaczyć cały statyw w debugerze? Czy to dlatego, że moje wywołania funkcji z setTimeout używają zamknięcia, aby uzyskać pewne zmienne lokalne? –

+1

@AranMulholland Gdzie wywołujesz debuggera? Wewnątrz funkcji, która jest przekazywana do 'setTimeout'? –

+0

@ ŠimeVidas, jak na pytanie, właśnie patrzę na callstack w debugger przeglądarki (Chrome i IE) –