Blokowanie możliwości wielokrotnego uruchomienia tej samej funkcji

JavaScript daje ogromne możliwości tworzenia dynamicznych i interaktywnych aplikacji. Czasami jednak możemy trafić na sytuację, w której dana funkcja jest wywoływana wielokrotnie, co powoduje nieprzewidziane problemy. Przykład? Kliknięcie przycisku kilka razy z rzędu, które uruchamia ten sam proces wielokrotnie. To może prowadzić do błędów, niechcianych efektów wizualnych albo przeciążenia serwera.

Dziś pokażę Ci, jak w prosty sposób zapobiec temu zjawisku, blokując możliwość wielokrotnego uruchomienia tej samej funkcji w JavaScript. Pokażę zarówno podstawowe techniki, jak i bardziej zaawansowane podejścia.

Dlaczego warto blokować wielokrotne wywołania funkcji?

Zanim przejdziemy do kodu, warto odpowiedzieć na pytanie: dlaczego w ogóle mielibyśmy się tym przejmować? Oto kilka przykładów sytuacji, w których takie zachowanie może być problematyczne:

  1. Wielokrotne żądania do serwera: Jeśli użytkownik kliknie przycisk „Wyślij” kilka razy z rzędu, może wysłać kilka żądań HTTP do serwera. To może prowadzić do duplikatów w bazie danych lub przeciążenia aplikacji.
  2. Animacje i efekty wizualne: Wywoływanie funkcji animacyjnych wielokrotnie w krótkim czasie może powodować migotanie albo wizualne błędy.
  3. Zwiększone użycie zasobów: Niepotrzebne wielokrotne uruchamianie tej samej logiki może wpłynąć na wydajność aplikacji.

Jak blokować wielokrotne wywołania?

Poniżej znajdziesz kilka praktycznych metod, które pozwolą Ci kontrolować, czy funkcja może być uruchomiona ponownie, czy nie.

1. Prosta blokada z użyciem flagi

Najprostszym sposobem jest wykorzystanie zmiennej (flagi), która śledzi, czy funkcja została już uruchomiona.

let isFunctionRunning = false;

function myFunction() {
    if (isFunctionRunning) {
        console.log("Funkcja już działa, poczekaj...");
        return;
    }

    isFunctionRunning = true;

    console.log("Funkcja uruchomiona!");

    // Symulacja działania funkcji przez 3 sekundy
    setTimeout(() => {
        isFunctionRunning = false;
        console.log("Funkcja zakończona, można uruchomić ponownie.");
    }, 3000);
}

// Test
myFunction(); // Uruchomi funkcję
myFunction(); // Zignoruje kolejne wywołanie

Jak to działa?

  • Flaga isFunctionRunning zmienia wartość na true, gdy funkcja się uruchamia.
  • Dopóki flaga ma wartość true, kolejne wywołania są ignorowane.
  • Po zakończeniu funkcji, flaga wraca na false.

2. Blokada za pomocą debounce

Kolejnym popularnym sposobem jest użycie techniki „debounce”. Dzięki niej funkcja będzie mogła zostać wywołana tylko raz w określonym przedziale czasu.

function debounce(func, delay) {
    let timeoutId;

    return function (...args) {
        if (timeoutId) return;

        func.apply(this, args);

        timeoutId = setTimeout(() => {
            timeoutId = null;
        }, delay);
    };
}

// Przykład użycia
const myDebouncedFunction = debounce(() => {
    console.log("Funkcja uruchomiona!");
}, 3000);

// Test
myDebouncedFunction(); // Uruchomi funkcję
myDebouncedFunction(); // Zignoruje kolejne wywołanie
setTimeout(myDebouncedFunction, 4000); // Uruchomi funkcję po 4 sekundach

Jak to działa?

  • debounce tworzy funkcję opóźnioną, która pozwala na uruchomienie tylko wtedy, gdy nie było żadnych wcześniejszych wywołań w określonym czasie (delay).

3. Blokada z użyciem once

Jeśli chcesz, aby dana funkcja mogła być uruchomiona tylko raz, możesz stworzyć specjalną wersję funkcji z wykorzystaniem „once”.

function once(func) {
    let hasRun = false;

    return function (...args) {
        if (hasRun) {
            console.log("Funkcja może być uruchomiona tylko raz!");
            return;
        }

        hasRun = true;
        return func.apply(this, args);
    };
}

// Przykład użycia
const myOnceFunction = once(() => {
    console.log("Funkcja uruchomiona po raz pierwszy (i ostatni)!");
});

// Test
myOnceFunction(); // Uruchomi funkcję
myOnceFunction(); // Zignoruje kolejne wywołanie

Jak to działa?

  • hasRun przechowuje informację, czy funkcja została już wywołana. Jeśli tak, kolejne próby zostaną zignorowane.

4. Zaawansowane podejście z użyciem Promise

Jeśli funkcja zwraca obietnicę (Promise), możemy zabezpieczyć się przed wielokrotnym jej uruchomieniem w trakcie działania.

let isRunning = false;

function asyncFunction() {
    if (isRunning) {
        console.log("Funkcja już działa, poczekaj...");
        return;
    }

    isRunning = true;

    return new Promise((resolve) => {
        console.log("Funkcja działa...");
        setTimeout(() => {
            console.log("Funkcja zakończona.");
            isRunning = false;
            resolve();
        }, 3000);
    });
}

// Test
asyncFunction();
asyncFunction(); // Zignoruje, bo funkcja jest w trakcie działania

Jak to działa?

  • isRunning działa jak flaga, ale tutaj jest używana w kontekście asynchronicznym.
  • Po zakończeniu funkcji flaga wraca na false, umożliwiając kolejne uruchomienie.

5. Biblioteki z gotowymi rozwiązaniami

Jeśli nie chcesz pisać własnych rozwiązań, możesz skorzystać z gotowych bibliotek, takich jak Lodash. Biblioteka ta oferuje funkcje debounce i throttle, które świetnie nadają się do blokowania wielokrotnych wywołań.

// Instalacja Lodash (npm lub CDN)
// npm install lodash

import _ from "lodash";

// Przykład użycia debounce z Lodash
const myDebouncedFunction = _.debounce(() => {
    console.log("Funkcja uruchomiona z debounce (Lodash)");
}, 3000);

// Test
myDebouncedFunction();
myDebouncedFunction(); // Ignorowane

Kiedy wybrać którą metodę?

  • Prosta flaga: Idealna do jednorazowych blokad na krótki czas.
  • Debounce: Przydatna, gdy chcesz opóźnić wielokrotne wywołania w krótkim okresie (np. obsługa kliknięć).
  • Once: Gdy funkcja ma być uruchomiona tylko raz (np. inicjalizacja aplikacji).
  • Promise: Dobre do blokowania wywołań funkcji asynchronicznych.

Blokowanie możliwości wielokrotnego uruchomienia funkcji w JavaScript to kluczowa technika w tworzeniu stabilnych i niezawodnych aplikacji. Dzięki opisanym metodom możesz w łatwy sposób uniknąć problemów, takich jak wielokrotne żądania do serwera czy nadmierne użycie zasobów.

Szukasz taniego i dobrego hostingu dla swojej strony www? - Sprawdź Seohost.pl