Muszę stworzyć funkcję, która może być wykonana tylko raz, za każdym razem po pierwszej nie zostanie wykonana. Wiem z C ++ i Javy o zmiennych statycznych, które mogą wykonać tę pracę, ale chciałbym wiedzieć, czy istnieje bardziej elegancki sposób, aby to zrobić?
javascript
function
design-patterns
vlio20
źródło
źródło
Odpowiedzi:
Jeśli przez „nie zostanie wykonany” masz na myśli „nic nie zrobi, gdy zostanie wywołany więcej niż raz”, możesz utworzyć zamknięcie:
W odpowiedzi na komentarz @Vladloffe (teraz usunięty): W przypadku zmiennej globalnej inny kod może zresetować wartość flagi „wykonane” (niezależnie od wybranej nazwy). W przypadku zamknięcia inny kod nie może tego zrobić, ani przypadkowo, ani celowo.
Jak wskazują inne odpowiedzi, kilka bibliotek (takich jak Underscore i Ramda ) ma małą funkcję użytkową (zwykle o nazwie
once()
[*] ), która przyjmuje funkcję jako argument i zwraca inną funkcję, która wywołuje podaną funkcję dokładnie raz, niezależnie od tego, jak wielokrotnie wywoływana jest funkcja zwracana. Zwracana funkcja również buforuje wartość zwróconą jako pierwsza przez podaną funkcję i zwraca ją przy kolejnych wywołaniach.Jeśli jednak nie korzystasz z takiej biblioteki innej firmy, ale nadal chcesz mieć taką funkcję użytkową (zamiast rozwiązania jednorazowego, które zaproponowałem powyżej), jest to łatwe do wdrożenia. Najładniejsza wersja, jaką widziałem, to ta opublikowana przez Davida Walsha :
Byłbym skłonny zmienić
fn = null;
sięfn = context = null;
. Nie ma powodu, dla którego domknięcie zachowuje odniesienie docontext
kiedyśfn
zostało wywołane.[*] Należy jednak pamiętać, że inne biblioteki, takie jak to rozszerzenie Drupala do jQuery , mogą mieć funkcję o nazwie,
once()
która robi coś zupełnie innego.źródło
if
wyrażeniu testu instrukcji) JavaScript oczekuje jednej z wartościtrue
lub,false
a przepływ programu reaguje zgodnie z wartością znalezioną podczas obliczania wyrażenia. Operatory warunkowe, takie jak==
zawsze, obliczają wartość logiczną. Zmienna może również posiadać albotrue
albofalse
. (Aby uzyskać więcej informacji, zapoznaj się z dokumentacją dotyczącą wartości logicznych , truey i falsey .)Zastąp go funkcją wielokrotnego użytku NOOP (brak działania) .
źródło
setInterval(foo, 1000)
- i już to nie działa. Po prostu nadpisujesz odwołanie w bieżącym zakresie.invalidate
Funkcja wielokrotnego użytku, która działa zsetInterval
itp.: Jsbin.com/vicipar/1/edit?js,consoleWskaż pustą funkcję po jej wywołaniu:
Lub tak:
źródło
setInterval()
), to odwołanie powtórzy pierwotną funkcjonalność po wywołaniu.UnderscoreJs ma funkcję, która to robi, underscorejs.org/#once
źródło
once
przyjmowanie argumentów. Możesz zrobićsquareo = _.once(square); console.log(squareo(1)); console.log(squareo(2));
i dostać1
za oba połączeniasquareo
. Czy dobrze to rozumiem?_.once
metody. Zobacz jsfiddle.net/631tgc5f/1_
; Nie polecałbym polegać na całej bibliotece w przypadku tak małego fragmentu kodu.Mówiąc o zmiennych statycznych, wygląda to trochę jak wariant zamknięcia:
Następnie możesz zresetować funkcję, jeśli chcesz:
źródło
źródło
Możesz po prostu mieć funkcję „usuń się”
Ale to może nie być najlepsza odpowiedź, jeśli nie chcesz połykać błędów.
Możesz też to zrobić:
Potrzebuję, aby działał jak inteligentny wskaźnik, jeśli nie ma elementów typu A, można go wykonać, jeśli jest jeden lub więcej elementów A, funkcja nie może zostać wykonana.
źródło
Once
zostanie przekazane jako oddzwonienie (npsetInterval(Once, 100)
.). Oryginalna funkcja będzie nadal wywoływana.Spróbuj tego
źródło
Od jakiegoś gościa imieniem Crockford ... :)
źródło
TypeError: Cannot read property 'apply' of null
to świetnie. To jest to, co otrzymasz po drugim wywołaniu zwróconej funkcji.invalidate
Funkcja wielokrotnego użytku, która współpracuje zsetInterval
:Wypróbuj na JSBin: https://jsbin.com/vicipar/edit?js,console
Odmiana odpowiedź od Bunyk
źródło
Oto przykład JSFiddle - http://jsfiddle.net/6yL6t/
A kod:
Mógłbyś:
I będzie działać tylko raz :)
źródło
Początkowe ustawienia:
źródło
Jeśli korzystasz z Node.js lub piszesz JavaScript w przeglądarce browserify, rozważ moduł jednorazowy npm :
źródło
Jeśli chcesz móc ponownie użyć tej funkcji w przyszłości, działa to dobrze w oparciu o powyższy kod ed Hoppa (zdaję sobie sprawę, że pierwotne pytanie nie wymagało tej dodatkowej funkcji!):
Wynik wygląda następująco:
źródło
prosty dekorator, który łatwo napisać, gdy potrzebujesz
za pomocą:
źródło
Próba użycia podkreślenia „raz”:
http://underscorejs.org/#once
źródło
źródło
Jeśli używasz Ramdy, możesz użyć funkcji „raz” .
Cytat z dokumentacji:
źródło
postaraj się, aby było to tak proste, jak to tylko możliwe
Możesz zobaczyć wynik
źródło
this
zamiastwindow
JQuery pozwala wywołać funkcję tylko raz za pomocą metody one () :
Implementacja z wykorzystaniem metody JQuery on () :
Implementacja przy użyciu natywnego JS:
źródło
źródło
Ten jest przydatny do zapobiegania nieskończonym pętlom (przy użyciu jQuery):
Jeśli martwisz się zanieczyszczeniem przestrzeni nazw, zamień długi, losowy ciąg na „doIt”.
źródło
Pomaga zapobiegać lepkiemu wykonaniu
źródło