2011-12-01 11 views
24

Funkcje jquery source używają funkcji setTimeout jako drugiego argumentu z 0 i 1. Mam wrażenie, że oba mają na myśli "wykonanie funkcji tak szybko, jak to możliwe".Różnica między setTimeout (fn, 0) i setTimeout (fn, 1)?

Czy to prawda? Czy istnieje różnica między tymi dwoma?

+20

1 ms ... – Leon

+2

@Leon : Miałem wrażenie, że przeglądarki nie mogą wykonywać z takim poziomem precyzji, podnosząc czas "setTimeout" do minimum 13 milisekund. – Randomblue

+0

Nigdy nie słyszałem o tej magicznej 13, ale oto cytat: "setTimeout w większości przeglądarek nie pozwala na opóźnienie mniej niż około 10 milisekund (wymusza dłuższe opóźnienia)" – Leon

Odpowiedz

9

Myślę, że odpowiedź brzmi: "To zależy" teraz.

Możemy uruchomić kod na innej platformie i przeglądarek:

function setTimeouts() { 
 
    setTimeout(function() { console.log(2); }, 2); 
 
    setTimeout(function() { console.log(1); }, 1); 
 
    setTimeout(function() { console.log(0); }, 0); 
 
} 
 

 
for (var i = 0; i < 10; i++) { 
 
    setTimeouts(); 
 
}

  1. Dla node.js, 0 jest przekształcany do 1, więc są one dokładnie takie same: https://github.com/nodejs/node/blob/master/lib/timers.js#L319 , a wynikiem może być:

    1 
    0 
    1 
    0 
    1 
    0 
    1 
    0 
    1 
    0 
    1 
    0 
    1 
    0 
    1 
    0 
    1 
    0 
    1 
    0 
    2 
    2 
    2 
    2 
    2 
    2 
    2 
    2 
    2 
    2 
    
  2. Dla Chrome, wynik jest całkiem podobna node.js

  3. for Firefox, większość 0 zostaną wydrukowane przed 1: różnica

    0 
    0 
    0 
    0 
    0 
    0 
    0 
    0 
    0 
    0 
    1 
    1 
    1 
    1 
    1 
    1 
    1 
    1 
    1 
    1 
    2 
    2 
    2 
    2 
    2 
    2 
    2 
    2 
    2 
    2 
    
2

Programowo i obliczeniowo jest różnica, ale nie jest to różnica, którą zobaczysz po uruchomieniu, ponieważ jest to tylko 1ms.

Wyobrażam sobie, że jeśli limit czasu jest ustawiony na 1ms, zatrzymuje ten skrypt i umożliwia uruchamianie innych skryptów w międzyczasie. I jak prawdopodobnie wiesz, javascript jest singlethreaded, więc to może być twój powód właśnie tutaj.

EDIT:

Dzięki @molf który poprawił moje myśli, wydaje się, że ustawienie go na 0ms to jedynie sztuczka, aby go uruchomić w następnym kleszcza pętli zdarzeń.

+3

Dlaczego tak by nie było z '0ms' też? Czy masz jakieś źródła? – molf

+0

Ma sens tylko, że jeśli zostanie ustawione na 0ms, uruchomi się natychmiast. Nie mam źródeł, dlatego napisałem "wyobrażam sobie" –

+3

Ustawienie "0" jest pospolitą sztuczką, aby kod działał w następnym teście pętli zdarzeń, nie powinien w ogóle działać natychmiast. – molf

27

setTimeout ma minimalny limit czasu 4ms. Tak naprawdę istnieje różnica między tymi dwoma wartościami.

Jeśli aktualnie działa zadaniem jest zadaniem, które zostało utworzone przez setTimeout() sposobu, a czas ten wynosi mniej niż 4, a następnie zwiększa timeout 4.

Spec

EDYCJA: Jak wskazał Ahmad w komentarzach, specyfikacja zmieniła się teraz, więc odpowiedź brzmiałaby teraz: "To zależy".

+0

Dzień, w którym wszystkie przeglądarki podążają za specyfikacjami do ms, będzie dla nas świetnym dniem dla twórców stron internetowych: D – Leon

+0

Rozdzielczość minimalnego timera bardzo zależy od platformy i przeglądarki. – jAndy

+0

Masz rację. Właśnie wypróbowałem [to] (http://pastehtml.com/view/bfupz16za.html) i okazało się, że różnica jest całkiem spora. Czasami mówi 3 dla mnie, a czasami mówi dla mnie 146. (Nie ustalony, bardzo często) –

-1

Jest to po prostu przykład złej praktyki kodu w źródle jQuery.

To wszystko. Nie ma powodu, by faworyzować 0 przez 1 lub vica versa.

Podnieś błąd jQuery, ustaw go/znormalizuj, aby używał jednego lub drugiego.

+0

proszę zdefiniować "zły kod". Czy myślisz, że istnieje rozwiązanie bez użycia 'setTimeout' (crossbrowser) lub po prostu dlatego, że użyli 1/0? Były Byłbym ciekawy twojej sugestii, ten drugi jest prawdopodobnie najlepszym zapachem kodu. – jAndy

+4

@jAndy Miałem na myśli fakt, że używają zarówno 0, jak i 1 w kodzie źródłowym. Tego rodzaju rzeczy nie powinny przejść przez przegląd kodu. jQuery powinien mieć przyzwoity przewodnik stylu i stosować go rygorystycznie – Raynos

+0

Dlaczego obwiniasz jQuery? Ta funkcja nie jest funkcją jQuery, jest wbudowana w JavaScript. –

1

powodów dlaczego setTimeout (fn, 0) lub setTimeout (fn, 1) jest potrzebny, sprawdź Why is setTimeout(fn, 0) sometimes useful?

W istocie oznacza to, że ta metoda nie jest bardzo pilne do wykonania w porównaniu do innych zadań przeglądarek takich jak strony wykonanie. Co więcej, kod js będzie działał po zakończeniu zadań oczekujących. Praktyczne, nie ma różnicy między używaniem 0 lub 1. To tylko wybór programisty. W idealnym przypadku liczba wybrana przez programistów jest mniejsza niż 4, co może wynikać z powodu wskazanego przez Amaan.

btw, do podstawowych informacji na temat timerów JavaScript, patrz http://ejohn.org/blog/how-javascript-timers-work/

4

nie jestem pewien podane odpowiedzi są poprawne.Uruchomiony następujący kod w Chrome 0 wyraźnie szybciej wywołując funkcję związaną (wystarczy przełączyć wartości timera między 0 i 1):

console.log("A"); 
console.log("B"); 
var start = new Date().getTime(); 
setTimeout(function() { 
    console.log(new Date().getTime() - start); 
}, 0); 
console.log("C"); 
console.log("D"); 

0 zdaje się robić coś takiego NodeJS na setImmediate, spychając dyspozycję na koniec bieżącego stosu wywołań, podczas gdy 1 wywołuje cokolwiek implementacja uważa za wartość minimalną.

+0

Drobna korekcja: Funkcja, do której odnosisz się w węźle nazywa się process.nextTick, podczas gdy setImmediate jest nowym wprowadzeniem do IE10, które robi to samo. – Wolverine

+0

Nie znalazłem żadnej stałej korzyści z używania '0' vs' 1' w powyższym teście. Czasami wynik był większy z "0", a czasami był większy przy "1". – gfullam