JavaScript 24.11

Zdarzenia na formularzach

Submit - wysłanie, prevent deflaut nie wysyłał, było wcześniej

Reset - czyści formularz, możemy przechwycić takie zdarzenie i zapobiec mu, możemy zapytać użytkownika czy na pewno chce zresetować?

Change - działa tak, że wywołuje się jeżeli wartość się zmieni i element straci focus, kiedy mamy kilka list rozwijanych i np wybieramy na pierwszej cos to druga lista jest zależna od tego wyboru. Dla select checkbox i radio jest natychmiastowy.

Input - wywołuje się przy każdej zmianie natychmiast

requestSubmit - programowo, są dwie metody: 1. submit i koniec, formularz zostanie wysyłany ale nie wywołuje zdarzenia sumbit 2. requestSubmit mówi przeglądarce wykonaj standardowa metodę wysyłanie formularza wywołuje submit event

Walidacja Formularzy

Łączy HTML i JS, oznacza to, że potrzebujemy gotowego pliku, załadowanego drzewa DOM, sparsowanego do pamięci aby wykonać poprawną walidację. Mamy w JS eventy do sprawdzenia czy DOM się załadował.

DOMContentLoaded - DOM gotowy, zostało załadowane, ale zasoby mogą być nie załadowane (obrazki, media, filmy, zewnętrzne style CSS). Używamy jeśli interesuje nas tylko DOM

Load event - wszystkie treści ze strony zostały załadowane. Możemy go wywołać nie tylko na całym dokumencie ale np. na konkretnym obrazku, możemy w tej sposób obsługiwać np. miniatury obrazków a po kliknięciu na osobnym div chcemy pokazać duży obrazek, więc zanim się załaduje to chcemy np pokazać animacje że się coś ładuje.

BeforeUnload - formDirty = false, kiedy gdy zamykamy stronę, kartę przeglądarki, przeglądarkę, np. użytkownik nie zakończył transakcji to jesteśmy w stanie to zdarzenie przechwycić i wyświetlić użytkownikowi ostrzeżenie, zapisać takie dane do cash użytkownika i jak wróci to będzie miał swój wypełniony formularz

Validity- to obiekt, który informuje, dlaczego pole formularza jest poprawne lub nie. Czy pole jest poprawnie wypełnione, jaki rodzaj błędu wystąpił, dlaczego przeglądarka uważa pole za niepoprawne.

Check Validity - true/false, form.checkValidity();

Real time input validation:

Debounce opóźnia wykonanie funkcji, aby nie uruchamiała się zbyt często.

Debounce async - jak wpisujemy nazwę użytkownika, wysyłamy do serwera zapytanie czy taki użytkownik może być zapisany, w asynchroniczny sposób to sprawdza czy użytkownik skończył i wysyła się do funkcji która sprawdza czy nazwa jest dostępna.

Throttle powoduje, że funkcja wykona się najwyżej raz na X milisekund. wykonuje się regularnie w trakcie trwania akcji

input.value - sięgnięcie do pola, najpierw getelementbyid


AI Tools

Large Language Model (AI) LLM

Wiele zadań na raz vs. jedno po drugim

Co program na robić, czego oczekuje pisze to modelowi i proszę go o przeanalizowanie logiki - daje to dobry plan aby zbudować aplikacje. Jeśli wszystko wymyśliłem poprawnie to model wskaże ulepszenia itd. ale np. z grubsza a dobrze ale bez wzięcia pod uwagę ważnych aspektów i model wskaże więcej - lepiej jedno


Asynchroniczność

W JS kod wykonuje się linia po linii, sekwencyjnie. Każda operacja musi zakończyć się zanim kolejna będzie możliwa do uruchomienia. Jeśli jakaś operacja będzie długa to zablokuj nam stronę. W JS w domyślnie wszystkie operacje są synchroniczne - linia po linii.

Asynchroniczność jest kluczowa z przeglądarce, bo nie chcemy blokować interfejsu użytkownika podczas kalkulowania, podczas oczekiwania na dane z serwera itp. Chcemy by dalej aplikacja była responsywna.

setTimeout - setTimeout wykonuje się raz po zadanym czasie, nie blokuje wykonania, oznacza, że mamy 2 sekundy i po tym czasie kod się wykonał. Nie jest to "prawdziwa" asynchroniczność, to symulacja tego jak chcemy by taki asynchroniczny kod działał.

setInterval - nie blokuje wykonania, setInterval to funkcja która wykonuje się cyklicznie. Wykonuje się za każdym razem jak zdefiniowane okno czasowe minie. np. automatyczne odświeżanie strony, automatyczne triggerowanie jakiejś akcji co jakiś czas. Jeśli nie zadeklarujemy końca to będzie wykonywał się bez końca, aby uniknąć tego trzeba ustawić licznik w tym interwale if (counter ===5){clearIntervwal(intervalid); }

Callbacks- aby uniknąć callback hell wprowadzono mechanizm promises - obietnice że coś się wykona, zwróci jakiś wynik

Promise - obiekt, który reprezentuje ostateczne zakończenie, lub ostateczne niepowodzenie operacji asynchronicznej. Tworzymy za pomocą konstruktora, funkcja ma 2 parametry resolve i reject. resolve przy sukcesie i reject by błędzie. Promis może być w 1 z 3 stanów: pending, fullfiled, rejected. Stan promise może zmienić się tylko raz.

  • Pending (oczekujący) - operacja jeszcze trwa
  • Fulfilled (spełniony) - operacja zakończona sukcesem
  • Rejected (odrzucony) - operacja zakończona błędem

To rozwiązuje problem callback, dlatego, że jesteśmy w stanie kontrolować jak się zakończyła poprzednia operacja i na jej podstawie wykonywać kolejne elementy. Nie musimy bazować na timerach bo mogą nie wystarczyć, lub nasz kod nie wykona się tak jakbyśmy oczekiwali. Na podstawie stanu możemy kontrolować czy kod wykonywać dalej czy nie, sposób który nie blokuje nam kodu (pobieranie danych od użytkownika)

To pozwala też obsługiwać błędy.

Then - obsługa sukcesu, wykonuje się, gdy Promise zostanie spełniony (fulfilled). then() może przyjąć DWA argumenty fulfiled i rejected. Zwraca operację asynchroniczną i pozwala na zareagowanie jeśli w poprzednim etapie mieliśmy sukces. Ważne: then() zawsze zwraca nowy Promise, dlatego można je łączyć w łańcuch. Nie blokuje, asynchronicznie jeśli jest fullfiled

Catch - .catch() Wykonuje się, gdy Promise zostanie odrzucony (rejected) lub gdy w then() wystąpi błąd. catch() łapie błędy z całego łańcucha.

Finally - .finally() Wykonuje się zawsze - niezależnie od tego, czy Promise zakończył się sukcesem czy błędem. Ważne: finally() nie otrzymuje argumentów - nie wie, czy Promise się powiódł czy nie. Służy aby np. posprzątać zasoby, zamknąć połączenia, ukryć loader.

Nie trzeba zawsze wszystkich 3 wykonywać, jeśli mamy 100% pewność że nasza operacja się uda to wystarczy then. Jeśli nie mamy pewności, to użyć wszystkich.

Łańcuchowanie (Promise chaining) - łączenie wielu operacji asynchronicznych w płaski łańcuch wywołań. Każdy then zwraca nowy promise. Widać co i kiedy się wydarzy a jednocześnie nie blokujemy kodu. Następny then czeka.

Promise.all() - czeka na wszystkie obietnice, tablica promisów, jako wynik zwraca 1 promise który rozwiązuje się jako sukces jeśli wszystkie promisy w takiej tablicy zakończą się sukcesem

Promise.race() - zwraca pierwszą zakończoną obietnicę, wynik. pierwszy wygrywa, jeśli mamy 5 promisów to pierwszy który się zakończy zwróci sukces, jeśli nie będzie ani jednego to zwraca porażkę

Promise.allSetled() - czeka na wszystkie promisy, czeka aż każdy się zrealizuje będzie w stanie settle (resolved lub rejected) i zwraca tablicę ze statusem


Tworzenie własnych funkcji które działają asynchronicznie:

Async/Await to nowoczesny sposób obsługi operacji asynchronicznych. To "cukier składniowy" (syntactic sugar) nad Promises - działa na Promises, ale wygląda jak zwykły synchroniczny kod.

async - deklaracja funkcji asynchronicznej. Słowo kluczowe async przed funkcją sprawia, że zawsze zwraca ona Promise. Możemy użyć od razu then.

await - czekanie na Promise. Słowo await wstrzymuje wykonanie funkcji do momentu rozwiązania Promise. Można go używać tylko wewnątrz funkcji async. Await zawiesza wykonanie funkcji, ale nie blokuje działania kodu, on sobie czeka na rozwiązanie tego promisa.

Podsumowanie:

  • async przed funkcją sprawia, że zwraca Promise
  • await wstrzymuje wykonanie do rozwiązania Promise
  • To nadal Promises "pod spodem"
  • Używaj try/catch do obsługi błędów
  • Dla wielu operacji równoległych używaj Promise.all()
  • Można używać tylko wewnątrz funkcji async (z wyjątkiem modułów)

Async/Await to najlepszy sposób na pisanie asynchronicznego kodu w JavaScript!