Języki skryptowe JavaScript Materiały https://github.com/getify/You-Dont-Know-JS • Strony internetowe: https://www.w3schools.com/js https://www.udemy.com https://eloquentjavascript.net https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide https://developer.mozilla.org/en-US/docs/Learn/JavaScript https://mva.microsoft.com/en-us/training-courses/javascriptfundamentals-for-absolute-beginners Popularność JavaScript Historia Historia JavaScript 1995 JavaScript 1.0 - Netscape Navigator (LiveScript) 1996 JScript - Microsoft TypeScript (Microsoft) 1997 ECMAScript 1.0 (ECMA-262) pierwszy standard JavaScript Language 1999 ECMAScript 3.0 ES6 (ES2015, ECMA) 1996 – 2001 “Wojna przeglądarkowa” MS Netscape Standard ES5 (ECMA) XMLHttpRequest -> AJAX (Asynchronous …) 2007 ECMAScript 4.0 Standard 2009 ECMAScript 5.0 (ES5) 2012 TypeScript (Microsoft ) 2015 ECMAScript 6.0 (ES6), ES2015 … 2022 ECMAScript 13 ECMA European Computer Manufacturers Association Historia • ES5 • Nowe obiekty i właściwości • Tryb ścisły (strict mode) – wykluczenie przestarzałych konstrukcji JS – deklaracja tego trybu poprzez “use strict”; • ES6 • Tryb ścisły – domyślny w modułach, klasach • Znaczące zmiany np.: klasy, obietnice • Transkompilatory ES6 -> ES5 np. Babel Zastosowania JavaScript • Strony internetowe - klasyka • Aplikacje internetowe np.: Google maps, prezentacje RevealJS, gry • Aplikacje serwerowe, serwery www: NodeJS np. Wal-Mart – MEAN (Mongo, Express, Angular, Node), ExpressJS – jako kluczowy element • Aplikacje na urządzenia mobilne:Phonegap, React Native (np. Facebook, Instagram, Gyroscope), oraz urządzenia smartwatch • Przenaszalne aplikacje desktopowe – Electron (np. Visual Studio Code, Atom) • Aplikacje chmurowe – bezserwerowe – serverless • MongoDB, CouchDB – język skryptowy i zapytań • Wiele innych … Strony internetowe Aplikacje chmurowe bezserwerowe Podstawowa składnia Podstawowa składnia Brak funkcji main() Podstawowa składnia Komentarze Java/C++ (/* */ także dozwolone) Podstawowa składnia Deklaracje zmiennych: - nie są wymagane (< ES5), ”use strict”, wymagane ES6 - brak specyfikacji typu zmiennej Podstawowa składnia Średniki na końcu nie wymagane … ale pożądane Podstawowa składnia Operatory arytmetyczne takie jak Java/C++ Podstawowa składnia Operator łączenia tekstów Podstawowa składnia Argumenty funkcji mogą być dowolnymi wyrażeniami Argumenty oddzielamy przecinkami Podstawowa składnia Dostęp do właściwości/metod obiektu - notacja z kropką Java/C++ Podstawowa składnia Podstawowa składnia Wiele struktur organizacji wykonywania oraz bloki { } identyczne jak w Java/C++ Podstawowa składnia Większość operatorów jak w Java/C++ Podstawowa składnia Automatyczna konwersja typów: guess - String, thinkingOf - Number Cechy języka JavaScript • Interpretowany • Dynamiczny • Zmienne nie mają określonego typu, można tworzyć nowe zmienne w czasie działania programu • W dowolnym momencie można tworzyć nowe funkcje i zastępować już istniejące • W czasie wykonywania można dodawać nowe właściwości do obiektów • Wymaga środowiska uruchomieniowego np.: przeglądarka, NodeJS Typy danych i zmienne • Typ zmiennej jest dynamiczny: zależy od typu danych zawartych w zmiennej • JavaScript ma 6 typów danych: • • • • • • number string boolean (true i false) null (jedyną wartością tego typu jest null) undefined (wartość nowo utworzonej zmiennej) object • Proste (primitive) typy danych – wszystkie oprócz object Typy danych i zmienne - typeof • Operator typeof zwraca typ testowanej zmiennej w postaci napisu • Ale ze względu na kompatybilność ze starymi wersjami Typy danych i zmienne - typeof • Pozostałe przykłady • W JavaScript zmienne nie mają typów, to wartości zmiennych posiadają typ • Użycie typeof jest pytaniem o aktualny typ wartości pamiętanej w zmiennej Zmienne – deklaracja i inicjalizacja • Mylący komunikat przeglądarki – błąd skryptu !!! • Powód takiego zachowania ( typeof nigdy nie powoduje błędu) Zmienne – deklaracja i inicjalizacja • Dostęp do nieistniejących właściwości obiektu nie powoduje błędu skryptu • Ale poziom głębiej już tak Zmienne – deklaracja i inicjalizacja • Nazwy zmiennych mogą się składać z kombinacji liter, cyfr, oraz znaków _ i $, nie mogą się zaczynać od cyfry, rozróżniane są duże i małe litery, zabronione słowa kluczowe • Inicjalizacja wartości zmiennej może być wykonana jednocześnie z jej deklaracją Operatory + * / % ++ -- dodawanie odejmowanie mnożenie dzielenie modulo inkrementacja dekrementacja = =, === równość ! =, !== nierówność ! logiczne NOT && logiczne AND || logiczne OR ? Wybór warunkowy Literały – typ number • Dla stałych w systemach: szesnastkowym, oktalnym, binarnym przedrostki: 0x, 0o, 0b , oktalne – także forma 0363 Literały – typ number – wartości specjalne • Nieskończoność • Nie-liczba (NaN) Literały – typ string • Pojedyncze albo podwójne apostrofy Typ string – automatyczne konwersje • Podwójne znaczenie operatora + (suma arytmetyczna, sklejanie napisów) może być źródłem błędów • Pozostałe operatory arytmetyczne powodują wykonanie konwersji na typ number – leniwa metoda konwersji • W przypadku niepowodzenia otrzymujemy NaN Typ string – automatyczne konwersje • Konwersja typ numer na string poprzez złączenie z pustym napisem Typ string – znaki specjalne • W łańcuchach napisowych można zawierać znaki specjalne, poprzedzane są one znakiem „specjalnym” \ • \n –koniec linii • \r – powrót karetki • \\ • \t • \u Typ string – literały szablonów • Literały szablonów ujęte są w znaki ` (backtick) • przykład klasyczny • przykład z szablonami Typ string – literały szablonów • Wewnątrz szablonów można używać wyrażeń, czy też wywołań funkcji Literały -typ boolean Operatory logiczne i konwersja •! Logiczna negacja • && logiczny AND • || logiczny OR • Użycie operatora logicznego na wartości innego typu niż boolean spowoduje przeprowadzenie automatycznej konwersji • Podwójną negacją można dokonać konwersji dowolnego typu na boolean Operatory logiczne i konwersja • Zasada konwersji dowolnej wartości na typ boolean – wynikiem konwersji jest true oprócz następujących przypadków: • • • • • • Pusty napis ”” Null Undefined Liczba 0 Liczba NaN Logiczne false • Kolejność operacji logicznych !, &&, || , • lepiej stosować nawiasy !!! Operatory logiczne – „leniwe” (shortcircuit) obliczanie wartości • Jeżeli wynik wyrażenia jest z góry przesądzony po obliczeniu jego początkowego fragmentu, dalsze obliczanie wyrażenia jest porzucane Operatory logiczne – „leniwe” obliczanie wartości • „leniwe” obliczanie wartości wyrażenia powoduje ciekawy efekt uboczny – zwracanie wartości typu nie-boolean, jeśli takowa występuje w wyrażeniu • Deklaracja i definicja zmiennej, co do której nie jesteśmy pewni czy już istnieje (jeśli istnieje, pozostaw jej aktualną wartość) • Uwaga jednak na zmienne z wartością dającą false Operatory logiczne – porównywanie == Przed porównaniem argumenty konwertowane do tego samego typu === Sprawdzenie równości, oraz zgodności typów, brak niekontrolowanej konwersji typów !!! != !== Sprawdzanie różności (z konwersją) > 1 == 1; true > 1 ==2; false > 1=='1'; true Sprawdzanie różności bez konwersji > 1 ==='1'; false > 1 ===1; true Tablice • Tablice są zasobnikami wartości dowolnego typu • Automatycznie dostosowują swój rozmiar do zawartości Tablice • Można wstawiać elementy pod dowolnym indeksem – powstają wtedy tablice „rzadkie” (sparse arrays) Tablice • Tablice można też indeksować kluczami nienumerycznymi, takie elementy tablicy nie są zaliczane do jej długości (oprócz kluczy konwertowalnych na typ całkowity), tablica jest obiektem ! Tablice • Usuwanie elementów tablicy możliwe jest za pomocą operatora delete • Tablice można zagnieżdżać Wartości i referencje • W JS zmienne są przekazywane przez wartość lub referencję, ale zależy to tylko od typu wartości zmiennej • Wszystkie typy podstawowe (number, string, boolean, null, undefined) przekazywane są przez wartość, natomiast pozostałe przekazywane są przez referencję Wartości i referencje • b jest teraz referencją do innego obiektu Wartości i referencje • Ciekawy przykład na działanie referencji Bloki kodu • Bloki kodu ograniczane są nawisami {}, można je zagnieżdżać dowolnie głęboko Wyrażenia warunkowe - if • Wyrażenie warunkowe if może być łańcuchowo połączone dowolną ilość razy za pomocą klauzuli else • Alternatywna składnia dla prostych przypisań Wyrażenia warunkowe - case Pętle- while i do-while Pętle- for Kolejność wykonywania: • Inicjalizacja – blok O • Obliczenie warunku logicznego – blok C, jeśli wartość true to • Wykonaj blok kodu L • Wykonaj wyrażenie inkrementujące ++ Pętle- for - in Służą do przeglądania właściwości kontenerów np.: tablic bądź obiektów, do przeglądania tablic zalecane są jednak pętle for. For-in zwraca klucze tych właściwości Pętle- for - of Służą do przeglądania zawartości obiektów obsługujących specjalny protokół (@@iterable) – np wbudowane: String, Array, Map, Set. Zwracane są całe iterowalne elementy Komentarze • Komentarz pojedynczej linii – znaki // na jej początku • Komentarz większego bloku – pomiędzy znakami /* i */ Funkcje Pozwalają na wielokrotne wykorzystywane tego samego fragment kodu • • • • Słowo kluczowe function Nazwa funkcji Lista parametrów oddzielana przecinkami (0..n) Opcjonalne wyrażenie return zwracające pojedynczą wartość, więcej – można użyć np. tablicy • Jeśli nie ma wyrażenia return funkcja zwraca wartość undefined Wywołanie funkcji: Funkcje - wywoływanie • Opuszczonym argumentom przy wywołaniu funkcji JS nadaje wartość undefined • Nadmiarowe argumenty są ignorowane • Wewnątrz funkcji jest zdefiniowana specjalna zmienna arguments pozwalająca uzyskać dostęp do wszystkich argumentów wywoływanej funkcji w postaci tablicy Funkcje – lista parametrów • Zmienną arguments można wykorzystać do realizacji funkcji przyjmującej dowolną ilość argumentów Funkcje – parametry domyślne • Parametrom funkcji można przypisać wartości domyślne • Parametry domyślne posiadają własny zakres umieszczony pomiędzy zewnętrznym i wewnętrznym zakresem funkcji Funkcje – parametry reszty • W ES6 pojawiły się parametry tzw. reszty • Parametr reszty może się pojawić raz i tylko jako ostatni na liście parametrów funkcji • Oznaczany jest za pomocą … przed ostatnim parametrem formalnym • Parametr ten staje się tablicą (w odróżnieniu od arguments jest to prawdziwa tablica ze wszystkimi metodami) Operator rozwijania (spread) • Operator ten zastosowany do tablicy powoduje jej rozbicie na poszczególne elementy • Ułatwia manipulowanie tablicami Funkcje predefiniowane – parseInt() • parseInt() konwertuje napis na liczbę całkowitą, opcjonalny drugi parametr – podstawa liczby • parseInt() próbuje również interpretować podstawę na podstawie przedrostka liczby Funkcje predefiniowane – parseFloat() • parseFloat() konwertuje napis na liczbę zmiennoprzecinkową Funkcje predefiniowane – isNaN() • isNaN() sprawdza czy argument funkcji jest typem liczbowym • Dokonuje również konwersji z napisów • Przydatna do testowania ponieważ wynikiem porównania NaN === NaN jest false Funkcje predefiniowane – eval() • Funkcja eval() przymuje jako argument łańcuch znaków i wykonuje go jako kod JS • Należy unikać używania z powodów bezpieczeństwa oraz wydajnościowych Zakres zmiennych – globalny • Zmienne globalne są dostępne i modyfikowalne z dowolnego miejsca kodu • Deklarowane są na zewnątrz funkcji • W przypadku przeglądarek zmienne globalne stają się właściwościami globalnego obiektu window Zakres zmiennych – globalny • Zmiennych globalnych należy używać z rozwagą, a najlepiej unikać – mogą być źródłem trudnych do odnalezienia błędów • W razie konieczności lepiej stworzyć jeden obiekt globalny • W NodeJS główny zakres nie jest zakresem globalnym – jest lokalnym dla aktualnego modułu • Globalna zmienna w NodeJS wymaga użycia obiektu (przestrzeni nazw) global Zakres zmiennych – globalny • Deklaracja zmiennej bez któregoś z var, let, const tworzy zmienną globalną ! (pamiętamy o trybie ścisłym ”use strict”) Zakres zmiennych – lokalny • Zmienne zadeklarowane wewnątrz funkcji mają zakres lokalny ograniczony do tej funkcji Zakres zmiennych – wynoszenie (hoisting) • Co zostanie wypisane na konsoli ? • Zmienne deklarowane w JavaScript podlegają tzw. wynoszeniu - • Deklaracja zmiennej z użyciem var w ukryty sposób przenoszona jest do góry odpowiadającego jej zakresu Odpowiednik kodu powyżej Zakres zmiennych – ES6 - let • Słowo kluczowe let ogranicza zasięg zmiennej do najbliższego bloku kodu • Brak wynoszenia • Zmienna globalna z let nie staje się właściwością window Zakres zmiennych – ES6 - const • Zasady zasięgu jak w let • Nie można jednak zmieniać pierwotnego przypisania do tych zmiennych Zakres zmiennych – ES6 - const • Uwaga jak zmienne const zachowują się w przypadku obiektów • Można natomiast zmieniać wnętrze obiektów • Object.freeze zamyka wnętrze obiektu przed modyfikacjami Zakres zmiennych – zakres globalny <-> lokalny • Redeklaracja zmiennej w zakresie lokalnym – powstaje inna, nowa zmienna, dostęp do globalnej przez obiekt window • Czytelniejsza wersja z let i specjalnym, stworzonym przez siebie obiektem globals Zakres zmiennych – var, let, const Słowo kluczowe Zakres Wynoszenie zmiennych Zmiana przypisania Redeklaracja var funkcji tak tak tak let bloku nie tak nie const bloku nie nie nie Funkcje jako dane • Funkcję można przypisać do zmiennej • Zapis literałowy funkcji (literal notation) • To jest wyrażenie funkcyjne nienazwane – funkcja anonimowa • Dodanie opcjonalnej nazwy tworzy nazwane wyrażenie funkcyjne • Typ danych – „function” • Specjalny ponieważ: • Zawiera kod • Jest wykonywalny Funkcje jako dane • Tak jak z każdym innym typem danych funkcje można przypisywać do zmiennych Funkcje – wywołania zwrotne • Wywołanie invokeAdd z parametrami, • funkcje one, two są funkcjami wywołania zwrotnego (callback functions) • To samo, zwarty zapis Funkcje – wywołania zwrotne • Zakładając, że każdy wynik pierwszego wywołania chcemy podać do drugiej funkcji • Wada poniższego rozwiązania – podwójne pętle Funkcje – wywołania zwrotne • Wersja z wywołaniem zwrotnym • Wersja z wywołaniem zwrotnym i funkcja anonimowa Funkcje natychmiastowe • Funkcja wywoływana natychmiast po jej zdefiniwaniu • Wersja alternatywna • Funkcje natychmiastowe nadają się wykonywania jednorazowych działań np.: inicjalizacja • Mogą coś zwracać Funkcje wewnętrzne (prywatne) • Funkcję można zdefiniować wewnątrz innej funkcji • Funkcja inner nie jest dostępna z zewnątrz • Funkcje wewnętrzne umożliwiają udostępnienie na zewnątrz (innym programistom) tylko określonych wywołań • Nie zaśmiecana jest globalna przestrzeń nazw Funkcje zwracające funkcje • Skoro funkcja to typ danych to można napisać funkcję zwracającą inną funkcję • Jak zadziała takie wywołanie ? • A jak takie ? (pierwsze i drugie wywołanie a) • W tym wypadku funkcja zmodyfikuje samą siebie (inny wynik przy pierwszym wywołaniu i inny w kolejnych) Funkcje - przykład Funkcje – domknięcia (closures) • Przypomnienie – zakres funkcji • Wewnątrz funkcji f() a i b są osiągalne • Na zewnątrz funkcji f() osiągalne jest tylko a a b f() Funkcje – domknięcia – łańcuch zakresów • Zagnieżdżone zakresy tworzą łańcuch zakresów • Funkcja inner() ma dostęp do wszystkich zmiennych w łańcuchu global outer_local Inner_local outer() inner() Funkcje – domknięcia a Zakres globalny - G b c F() N() Funkcje – domknięcia a Zakres globalny - G b c F() N() Zakres globalny - G a b • Efekt domknięcia występuje jeśli N() zostanie przesunięte do zakresu globalego F() c N() Funkcje – domknięcia - przykład 1 • Z zakresu globalnego nie ma dostępu do b • Ponieważ F() zwraca N() to N() może być przypisany do zmiennej globalnej, a N() ma dostęp do przestrzeni prywatnej F() Funkcje – domknięcia - przykład 2 • Po wywołaniu F() do zmiennej inner przypisana zostanie funkcja N(), można ją wywołać mimo tego że „brak” kontekstu funkcji F() • Każda funkcja generuje domknięcie – utrzymuje ukryte zmienne powiązanie z zakresem, w którym została utworzona • W większości przypadków zakres ten jest usuwany, chyba że wymusimy jego zapamiętanie Funkcje – domknięcia – przykład 3 • Parametry funkcji zachowują się jak zmienne lokalne danej funkcji • Inkrementacja dokonywana jest na zmiennej param po wykonaniu funkcji N() • Funkcja utrzymuje nie kopię a referencję do swojego nadrzędnego zakresu, jeżeli coś spowoduje modyfikację zmiennych w tym zakresie natychmiast to będzie widoczne w funkcji Funkcje – domknięcia – przykład 4 Funkcja utrzymuje nie kopię a referencję do swojego nadrzędnego zakresu, Jak spowodować żeby funkcje zwracały kolejne liczby? – jeszcze jedno domknięcie Funkcje – domknięcia – przykład 4 • Rozwiązanie problemu wersja a) • Każda iteracja to kolejne domknięcie Funkcje – domknięcia – przykład 4 • Rozwiązanie problemu wersja b) Domknięcia - funkcje dostępowe (getter - setter) Mechanizm domknięcia można wykorzystać do ukrycia zmiennej przed bezpośrednią manipulacją z zewnątrz, dostęp tylko przez funkcje dostępowe Domknięcia - iteratory Mechanizm domknięcia można wykorzystać do tworzenia iteratorów (generatorów sekwencji) Funkcje strzałkowe (arrow functions) Specyfikacja ES6 wprowadza możliwość bardziej zwięzłego definiowania funkcji Zasady stosowania w zależności od ilości parametrów funkcji: Brak: 1 parametr: Więcej 1: () => { …} a => {…} (a,b) => {…} Funkcje strzałkowe (arrow functions) Zasady stosowania w zależności od ilości parametrów funkcji: Brak: 1 parametr: Więcej 1: () => { …} a => {…} (a,b) => {…} Funkcje strzałkowe mogą zawierać zarówno wyrażenia jak i bloki instrukcji Obiekty Przykładowy obiekt: • • • • • Składowe obiektu nazywane są właściwościami Właściwości oddzielane są przecinkami Para nazwa właściwości (klucz) – wartość oddzielana jest dwukropkiem Klucze mogą być ujmowane w apostrofy (tak jak stałe napisowe) Zalecane nie jest ujmowanie nazw właściwości w apostrofy chyba że: • Nazwa jest słowem zarezerwowanym • Zawiera spacje bądź znaki specjalne • Zaczyna się od cyfry Obiekty - właściwości Właściwościami mogą być też funkcje - metody: Dostęp do właściwości obiektu: Notacja z kropką: Notacja z nawiasami: Obiekty - właściwości Obiekty można zagnieżdżać: Sposoby dostępu: Dla dynamicznie generowanych nazw właściwości notacja z nawiasami: Obiekty - metody Wzywanie metod: Obiekty – dodawanie/usuwanie właściwości Pusty obiekt: Dodawanie właściwości do obiektu : Usuwanie właściwości z obiektu : Dostęp do właściwości obiektu – klauzula this: Obiekty – konstruktory Do tworzenia obiektów można również używać konstruktorów (konwencja – zaczynają się od dużej litery): Nowy obiekt tworzymy wzywając funkcję konstruktora z operatorem new: Konstruktory mogą otrzymywać parametry: Obiekty – konstruktory Co jeśli konstruktor zostanie wezwany bez new ? this w takim przypadku będzie się odnosiło do zakresu globalnego Obiekty – właściwość constructor Nowo utworzony obiekt otrzymuje automatycznie właściwość constructor, która jest referencją do funkcji konstruktora Można ją wykorzystać do tworzenia podobnych obiektów Dla obiektów literałowych Obiekty – operator instanceof Operatorem instanceof sprawdzamy czy obiekt został stworzony odpowiednim konstruktorem Obiekty – fabryki obiektów Obiekty można też tworzyć zwykłymi funkcjami - Obiekty – przekazywanie i porównywanie Przypisanie obiektu do zmiennej, bądź jego przekazanie do funkcji oznacza operację na referencji Porównywanie obiektów również dotyczy referencji Literały obiektowe – ES6 W specyfikacji ES6 wprowadzono kilka uproszczeń dotyczących literałów obiektowych: - jeśli nazwa właściwości i zmiennej są takie same: - definicje metod: - obliczane nazwy właściwości i funkcji: Obiekty – właściwości i atrybuty obiektów Obiekty mają właściwości, pojedyncza właściwość ma klucz i atrybuty Atrybuty to m.in. : enumerable – czy dana właściwość jest wyliczalna configurable – czy można daną właściwość edytować, bądź usunąć Do pobierania atrybutów właściwości służy metoda Object.getOwnPropertyDescriptor - Definiowanie właściwości z kontrolą atrybutów: Obiekty – kopiowanie właściwości Metoda Object.assign służy do kopiowania wartości właściwości obiektu źródłowego do obiektu docelowego, właściwości istniejące w obiekcie docelowych a nie istniejące w źródłowym są ignorowane Do Object.assign można przekazać kilka obiektów źródłowych Destrukturyzacja - obiekty Często konieczne jest pobieranie wartości wybranych właściwości z obiektu: ES6 dostarcza prostszej składni (server i port to osobne zmienne !): Nazwa zmiennej inna niż nazwa właściwości: Destrukturyzacja - obiekty Jeśli kopiujemy właściwości do wcześniej zadeklarowanych zmiennych, przypisanie otaczamy nawiasami (): Wyrażenie destrukturyzacyjne ewaluuje do prawej strony wyrażenie, więc można je użyć wszędzie tam, gdzie jest oczekiwana wartość: Destrukturyzacja - tablice Wyrażeń destrukturyzacyjnych można używać także z tablicami: Można pominąć wybrane elementy tablicy: Zamiana wartości 2 zmiennych (niepotrzebna zmienna pomocnicza): Użycie operatora reszty: Programowanie asynchroniczne Jednowątkowy model synchroniczny: Programowanie asynchroniczne Model wielowątkowy: - wątki wymagają mechanizmów wzajemnej komunikacji i sychronizacji Programowanie asynchroniczne Model asynchroniczny: - jeden wątek, w związku z czym niepotrzebne są skomplikowane mechanizmy komunikacji - czas wykonania zadań taki sam jak w modelu jednowątkowym synchronicznym, chyba że wewnątrz zadań oczekuje się na wykonanie operacji blokujących (czytanie pamięci masowych, wywołania sieciowe itp.) Programowanie asynchroniczne Model asynchroniczny: - Jeśli bieżące zadanie natrafia na blokującą operację wejścia/wyjścia, wznawiane jest wykonywanie innego zadania Programowanie asynchroniczne - mechanizmy Metoda setTimeout() służy do wykonania operacji po odliczeniu zadanego czasu Operacja ta specyfikowana jest w postaci funkcji wywołania zwrotnego, a operacja powodująca jej wywołanie wstawiana jest do kolejki komunikatów po zadanym czasie. Wywołanie funkcji zwrotnej następuje zatem asynchronicznie. Mechanizm rejestrowania obsługi zdarzeń: Programowanie asynchroniczne - mechanizmy Mechanizm wywołań zwrotnych (callback): Taki styl przekazywania wywołań zwrotnych nazywa się CPS (Continuation-Passing Style) Programowanie asynchroniczne – promises - obietnice Specyfikacja ES6 wprowadza obietnice jako mechanizm alternatywny do wywołań zwrotnych, - używane są do pobierania wyników operacji wykonywanych asynchronicznie - bardziej czytelny kod - obietnica działa jak element zastępczy dla spodziewanego wyniku Obietnica może być w jednym z 3 stanów: - Oczekująca (pending) – dopóki wynik nie jest gotowy - Spełniona (fulfilled) – wynik gotowy - Odrzucona (rejected) – błąd Gdy obietnica zostanie spełniona lub odrzucona wykonywane są odpowiednie wywołania zwrotne kolejkowane metodą .then() obietnicy