Jako programista przeprowadziłem wiele rozmów kwalifikacyjnych dotyczących Node.js i zauważyłem powtarzający się motyw. Wielu kandydatów często zmaga się z rozróżnieniem między wywołaniami zwrotnymi a zamknięciami. Są to fundamentalne koncepcje JavaScriptu, które sprawiają problemy nawet doświadczonym programistom. Rozbijmy je i wyjaśnijmy nieporozumienia, od dewelopera do dewelopera.

Dlaczego w ogóle używamy wywołań zwrotnych?

Aby zrozumieć wywołania zwrotne, potrzebujemy krótkiej lekcji historii. JavaScript zawsze był asynchroniczny, ale narzędzia, które dziś uważamy za oczywiste, takie jak async/await i obietnicenie istniały. Zostały one włączone dopiero w ECMAScript 2016. Jak więc programiści radzili sobie z zadaniami asynchronicznymi wcześniej? Zgadza się, za pomocą wywołań zwrotnych.

Co to jest oddzwanianie?

Wywołanie zwrotne to zwykła funkcja, ale używana w nieco niekonwencjonalny sposób. Zamiast być wywoływana bezpośrednio, jest przekazywana jako argument do innej funkcji. Pozwala to uruchomić wywołanie zwrotne później, często po zakończeniu innej operacji.

Oto krótki przykład:

function myCallback() {
  console.log("My Callback function has been fired!");
}

setTimeout(myCallback, 3000); // Fires the callback after 3 seconds

W tym przykładzie myCallback jest przekazywane do setTimeout. Po trzech sekundach setTimeout wykonuje wywołanie zwrotne, rejestrując komunikat w konsoli. Wywołania zwrotne były metodą obsługi asynchronicznego zachowania we wczesnych dniach JavaScript. Choć nadal przydatne, zostały w dużej mierze zastąpione przez Promises i async/await dla nowoczesnego rozwoju.

Co wyróżnia zamknięcia?

Zamknięcia są kolejnym kluczowym pojęciem w JavaScript i wykorzystują zdolność języka do obsługi funkcji zagnieżdżonych. Zamknięcie występuje, gdy funkcja zachowuje dostęp do zmiennych swojego rodzica, nawet po zakończeniu wykonywania przez rodzica. Innymi słowy, zamknięcie "pamięta" środowisko, w którym zostało utworzone.

Oto praktyczny przykład:

function multiplier(x) {
  return function (y) {
    return x * y;
  };
}

const double = multiplier(2);
console.log(double(5)); // Outputs 10

W tym przypadku funkcja mnożnika zwraca funkcję zagnieżdżoną, która może uzyskać dostęp do zmiennej x z zakresu swojego rodzica. Zamknięcia świetnie nadają się do tworzenia funkcji z prywatnymi stanami lub budowania narzędzi wielokrotnego użytku, takich jak powyższy mnożnik.

Czy wywołanie zwrotne może być zamknięciem?

Oto trudna część. Tak, oddzwonienie może być również zamknięciem. Jednak kandydaci zazwyczaj mają problem z wyjaśnieniem tego, zwłaszcza gdy muszą zagłębić się w szczegóły. Jeśli wywołanie zwrotne opiera się na zmiennych z zakresu jego rodzica, działa jako zamknięcie. Na przykład:

function fetchData(apiUrl) {
    const apiKey = "secretKey";

    setTimeout(function callback() {
        console.log(`Fetching from ${apiUrl} with API key: ${apiKey}`);
    }, 2000);
}

fetchData("https://example.com");

W tym przypadku funkcja wywołania zwrotnego jest zarówno wywołaniem zwrotnym (przekazywanym do setTimeout), jak i zamknięciem (używa zmiennej apiKey z funkcji nadrzędnej). Ta podwójna rola często dezorientuje programistów podczas rozmów kwalifikacyjnych.

Podsumowując

Podsumujmy. Wywołania zwrotne i zamknięcia często potykają się nawet o doświadczonych programistów podczas rozmów kwalifikacyjnych. Wywołania zwrotne pozwalają zarządzać zadaniami asynchronicznymi poprzez przekazywanie funkcji jako argumentów, podczas gdy zamknięcia odblokowują możliwość dostępu do zmiennych funkcji nadrzędnej z poziomu funkcji zagnieżdżonej. I tak, czasami wywołania zwrotne mogą być również zamknięciami, gdy polegają na zakresie swojego rodzica. Zrozumienie tych pojęć nie tylko pomoże ci odpowiedzieć na trudne pytania podczas rozmowy kwalifikacyjnej, ale także pomoże ci napisać czystszy, bardziej wydajny kod w rzeczywistych projektach.

Wszystko zrozumiałeś? Dobrze. Teraz możesz zaliczyć następną rozmowę kwalifikacyjną.

5/5 - (2 głosy)