Przejdź do głównej treści
Grafika przedstawia ukryty obrazek

Callback Hell w PHP i JavaScript: Jak sobie z nim radzić?

Ilustracja tematu Callback Hell w PHP i JavaScript Jak sobie z nim radzi

Callback Hell, znany również jako "Pyramid of Doom", to problem, który pojawia się, gdy funkcje zwrotne (callbacki) zagnieżdżają się wielokrotnie w kodzie, powodując jego trudność w czytaniu, debugowaniu i utrzymaniu. Jest to szczególnie widoczne w JavaScript, ale może też wystąpić w PHP, zwłaszcza przy korzystaniu z asynchronicznych operacji.

Callback Hell w JavaScript

W JavaScript callback hell pojawia się, gdy wiele operacji asynchronicznych zależy od siebie nawzajem. Przykładem może być sekwencyjne żądania do API:

function fetchData(url, callback) {
    fetch(url)
        .then(response => response.json())
        .then(data => callback(null, data))
        .catch(error => callback(error, null));
}

fetchData('https://api.example.com/data1', (err, data1) => {
    if (err) console.error(err);
    else {
        fetchData('https://api.example.com/data2', (err, data2) => {
            if (err) console.error(err);
            else {
                fetchData('https://api.example.com/data3', (err, data3) => {
                    if (err) console.error(err);
                    else {
                        console.log('Pobrane dane:', data1, data2, data3);
                    }
                });
            }
        });
    }
});

Ten kod jest trudny do zarządzania, gdy liczba callbacków rośnie.

Rozwiązania w JavaScript

  1. Użycie Promisów
function fetchData(url) {
    return fetch(url).then(response => response.json());
}

Promise.all([
    fetchData('https://api.example.com/data1'),
    fetchData('https://api.example.com/data2'),
    fetchData('https://api.example.com/data3')
]).then(([data1, data2, data3]) => {
    console.log('Pobrane dane:', data1, data2, data3);
}).catch(error => console.error(error));
  1. Użycie async/await
async function fetchDataSequentially() {
    try {
        const data1 = await fetchData('https://api.example.com/data1');
        const data2 = await fetchData('https://api.example.com/data2');
        const data3 = await fetchData('https://api.example.com/data3');
        console.log('Pobrane dane:', data1, data2, data3);
    } catch (error) {
        console.error(error);
    }
}

fetchDataSequentially();

Callback Hell w PHP

W PHP problem Callback Hell pojawia się najczęściej w przypadku korzystania z bibliotek asynchronicznych, np. ReactPHP lub Guzzle do zapytań HTTP.

function fetchData($url, $callback) {
    $client = new GuzzleHttp\Client();
    $client->getAsync($url)->then(
        function ($response) use ($callback) {
            $callback(null, json_decode($response->getBody(), true));
        },
        function ($error) use ($callback) {
            $callback($error, null);
        }
    );
}

fetchData('https://api.example.com/data1', function ($err, $data1) {
    if ($err) echo $err;
    else {
        fetchData('https://api.example.com/data2', function ($err, $data2) {
            if ($err) echo $err;
            else {
                fetchData('https://api.example.com/data3', function ($err, $data3) {
                    if ($err) echo $err;
                    else {
                        echo 'Pobrane dane: ' . json_encode([$data1, $data2, $data3]);
                    }
                });
            }
        });
    }
});

Rozwiązania w PHP

  1. Użycie Promise w ReactPHP
use React\Http\Browser;
use React\Promise\all;

$client = new Browser();

$promises = [
    $client->get('https://api.example.com/data1')->then(fn($response) => $response->getBody()),
    $client->get('https://api.example.com/data2')->then(fn($response) => $response->getBody()),
    $client->get('https://api.example.com/data3')->then(fn($response) => $response->getBody())
];

all($promises)->then(function ($responses) {
    echo 'Pobrane dane: ' . json_encode($responses);
})->otherwise(function ($error) {
    echo 'Błąd: ' . $error->getMessage();
});
  1. Użycie Generatorów

PHP od wersji 5.5 wspiera generatory, co może pomóc w uproszczeniu kodu asynchronicznego:

function fetchData($url) {
    $client = new GuzzleHttp\Client();
    return function () use ($client, $url) {
        return $client->get($url)->getBody();
    };
}

$data1 = fetchData('https://api.example.com/data1');
$data2 = fetchData('https://api.example.com/data2');
$data3 = fetchData('https://api.example.com/data3');

echo 'Pobrane dane: ' . json_encode([$data1(), $data2(), $data3()]);

Podsumowanie

Callback Hell to poważny problem w programowaniu asynchronicznym, który może znacznie obniżyć czytelność kodu i utrudnić jego debugowanie. Zarówno w JavaScript, jak i w PHP, najlepszym podejściem do jego unikania jest stosowanie promisów, async/await lub innych technik abstrakcji. Wybierając odpowiednie narzędzia, można uczynić kod bardziej przejrzystym i łatwym w utrzymaniu.

24 lutego 2025 17

Kategorie

programowanie

Dziękujemy!
()

Powiązane wpisy

Grafika przedstawia Automatyczny motyw Bootstrap 53 na bazie pory dnia
4 stycznia 2025 6 min 71

Automatyczny motyw Bootstrap 5.3 na bazie pory dnia

php
Czytaj więcej
Ilustracja tematu Wyraenia regularne i ich obsuga w PHP oraz JavaScript
1 lutego 2025 5 min 19

Wyrażenia regularne i ich obsługa w PHP oraz JavaScript

php
Czytaj więcej
Obraz ilustrujacy Klasa Promise w PHP i jej zastosowanie
5 lutego 2025 7 min 39

Klasa Promise w PHP i jej zastosowanie

php
Czytaj więcej
Wymiana doświadczeń

Masz podobne doświadczenia?

Chętnie poznam Twoją perspektywę i porozmawiam o tym temacie szerzej.

Napisz do mnie

Każda perspektywa może wnieść coś wartościowego do dyskusji.

Twoja prywatność i pliki cookies

  1. Ta strona internetowa wykorzystuje wyłącznie niezbędne pliki cookies, które są wymagane do jej prawidłowego działania – m.in. do poprawnego wyświetlania treści, zapamiętania podstawowych ustawień przeglądarki oraz zapewnienia stabilności serwisu.
  2. Nie stosuję plików cookies w celach marketingowych, reklamowych ani analitycznych.
  3. Strona ma charakter wyłącznie informacyjny i nie zawiera formularzy kontaktowych, rejestracyjnych ani zakupowych, przez które dane mogłyby być przesyłane na serwer.
  4. Nie zbieram danych osobowych podczas zwykłego korzystania z witryny.
  5. Serwis nie korzysta z certyfikatu SSL, jednak ze względu na informacyjny charakter strony nie jest wymagane przesyłanie poufnych danych. Zalecam jednak, aby nigdy nie wpisywać haseł ani danych osobowych na stronach bez szyfrowanego połączenia.
  6. Korzystając z tej strony, wyrażasz zgodę na używanie wyłącznie niezbędnych plików cookies.

Więcej informacji znajdziesz w mojej polityce prywatności.