• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Jak przerwać pętlę w funkcji javascript?

Cloud VPS
0 głosów
730 wizyt
pytanie zadane 11 września 2022 w JavaScript przez Doge Gaduła (3,420 p.)
edycja 11 września 2022 przez Doge

Witam, posiadam następujący kod:

function funkcja()
{
    for(let i=0; i<400; i++)
    {
        let xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function() {
            if(this.status == 200)
            {
                if(document.querySelector(`#field${i}`)) document.querySelector(`#field${i}`).innerHTML = this.responseText;
            }
        };
        xhr.open('GET', `field_load.php?f=${i}`, true);
        xhr.send();
    }
}

ale chciałbym, aby gdy warunek if

if(document.querySelector(`#field${i}`))

się nie spełni, została przerwana funkcja, lecz po zapisaniu

if(document.querySelector(`#field${i}`)) document.querySelector(`#field${i}`).innerHTML = this.responseText;
else break;

dostaję błąd: Uncaught SyntaxError: Illegal break statement

W jaki sposób mogę to rozwiązać?

EDIT: Problem był w tym, że elementy #field rzeczywiście były utworzone przy sprawdzaniu, lecz zapytania zostały asynchronicznie wysłane i po zniknięciu tych pól, próbowały uzupełnić nieistniejące pola

ROZWIĄZANIE:

for(let i=0; i<400; i++)
    {
        let xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function() {
            if(this.status == 200 && this.readyState == 4)
            {
                //current_window !== 'field' kiedy naciśnięto przycisk od usuwania pól
                if(current_window !== 'field') { console.log('PRZERWANO'); return;}
                document.querySelector(`#field${i}`).innerHTML = this.responseText;
                console.log(`I: ${i}`);
            }
        };
        xhr.open('GET', `field_load.php?f=${i}`, true);
        xhr.send();
    }

 

3 odpowiedzi

+1 głos
odpowiedź 11 września 2022 przez Comandeer Guru (607,060 p.)

Instrukcja break nie działa, bo znajduje się wewnątrz funkcji, którą tworzysz wewnątrz pętli, a która zostanie wywołana już dawno po zakończeniu pętli.

Musiałbyś przenieść sprawdzanie, czy element istnieje poza funkcję, bezpośrednio do pętli. I będzie to o wiele czytelniejsze, gdy zastosujesz wtedy tzw. guard clause.

Czyli coś typu:

for ( let i = 0; i < 400; i++ ) {
	if ( !document.querySelector( '#idElementu') ) {
		break;
	}

	// Tworzenie żądania itd.
}

 

komentarz 11 września 2022 przez Doge Gaduła (3,420 p.)
edycja 11 września 2022 przez Doge

Nadal przy kodzie

for(let i=0; i<400; i++)
    {
        if(!document.querySelector(`#field${i}`)){ console.log('PRZERWANO'); break;}
        let xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function() {
            if(this.status == 200)
            {
                document.querySelector(`#field${i}`).innerHTML = this.responseText;
                console.log(`I: ${i}`);
            }
        };
        xhr.open('GET', `field_load.php?f=${i}`, true);
        xhr.send();
    }

wykonuje się cała pętla. Kod polega na tym, że po naciśnięciu przycisku, usuwają się wszystkie elementy #field. Najpierw dostaję normalnie

window_switch.js:24 I: 0
window_switch.js:24 I: 1
window_switch.js:24 I: 2
window_switch.js:24 I: 3
window_switch.js:24 I: 4

a po usunięciu elementów, dostaję

Uncaught TypeError: Cannot set properties of null (setting 'innerHTML')
    at Field.xhr.onreadystatechange (window_switch.js:23:64)
Field.xhr.onreadystatechange @ window_switch.js:23
XMLHttpRequest.send (async)
Field @ window_switch.js:28

395 razy

EDIT: Już znalazłem rozwiązanie

komentarz 11 września 2022 przez Comandeer Guru (607,060 p.)
I jakie jest rozwiązanie? Bo tutaj coś jest IMO mocno przekombinowane i warto byłoby to przemyśleć.
+1 głos
odpowiedź 11 września 2022 przez VBService Ekspert (256,600 p.)
edycja 11 września 2022 przez VBService

if(document.querySelector(`#field${i}`)) //sprawdzenie, czy istnieje element

nie prościej będzie pobrać z DOM-a elementy o id zaczynającym się od słowa "field", które istnieją za pomocą document.querySelectorAll np. w taki sposób

const fields = document.querySelectorAll('[id^="field"]');

 

całość

function funkcja()
{
    const fields = document.querySelectorAll('[id^="field"]');
    for (const [i, field] of fields.entries())
    {
        let xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function() {
            if(this.status == 200)
            {
                field.innerHTML = this.responseText;
            }
        };
        xhr.open('GET', `field_load.php?f=${i}`, true);
        xhr.send();
    }
}

 

komentarz 11 września 2022 przez Doge Gaduła (3,420 p.)
Ogólnie sprawdzę ten sposób, lecz tutaj chodziło mi bardziej o to, że jeżeli w trakcie wczytywania któregoś #field zostanie przerwane, aby się już nie kontynuowało, bo nie będzie pozostałych #field, ale problem nie był po stronie istnienia tych pól, tylko uzupełniania, ponieważ wszystkie żądania AJAX wysłały się i później próbowały uzupełnić pola. W temacie dodałem edit odnośnie rozwiązania tego problemu. Może trochę źle zadałem pytanie lub było niezrozumiałe, ponieważ nie było całości kodu.
0 głosów
odpowiedź 11 września 2022 przez doublechess Obywatel (1,300 p.)

Twórz nową linię w przeciwnym razie obejmuj nawiasami klamrowymi.

if(document.querySelector(`#field${i}`))
  document.querySelector(`#field${i}`).innerHTML = this.responseText;
else
  return;
komentarz 11 września 2022 przez Doge Gaduła (3,420 p.)
Nic to nie zmienia
komentarz 11 września 2022 przez doublechess Obywatel (1,300 p.)
if(document.querySelector(`#field${i}`))

Warunek jest nielogiczny według mnie. To sprawdza, np. element <p>, <span>.

Chociaż nie do końca, bo to sprawdza najwyraźniej istnienie elementu.

Jeżeli jest true, to funkcja z odpytaniem do serwera ma się zerwać tak?

Wyjdź z pętli i funkcji (break, return). Zakończ uruchamianie się funkcji (clearInterval).

komentarz 11 września 2022 przez Doge Gaduła (3,420 p.)
if(document.querySelector(`#field${i}`)) //sprawdzenie, czy istnieje element

document.querySelector(`#field${i}`).innerHTML = this.responseText; //jeśli istnieje, nadpisanie innerHTML tego elementu

else break; //jeżeli nie istnieje, przerwanie
komentarz 11 września 2022 przez doublechess Obywatel (1,300 p.)
No dobra, ale co ma przerwać całą funkcję, czy pętlę?

Funkcja, pętla ma się przerwać z jakiej przyczyny, co tam się wtedy ma dziać?
komentarz 11 września 2022 przez Doge Gaduła (3,420 p.)
Przerwanie to przerwanie, zaprzestanie wykonywania kodu, pozostały kod się nie wykonuje. Źle opisałem, ale break służy do przerwania pętli, funkcję się przerywa za pomocą return, lecz u mnie wszystko jedno, bo pętla jest na końcu funkcji.

Podobne pytania

0 głosów
1 odpowiedź 495 wizyt
pytanie zadane 28 stycznia 2023 w JavaScript przez Verone Nowicjusz (120 p.)
+2 głosów
2 odpowiedzi 622 wizyt
pytanie zadane 25 kwietnia 2022 w Java przez cfaniaczek Nowicjusz (200 p.)
0 głosów
1 odpowiedź 908 wizyt
pytanie zadane 29 października 2020 w Java przez stronek1899 Nowicjusz (160 p.)

93,459 zapytań

142,454 odpowiedzi

322,724 komentarzy

62,837 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Kursy INF.02 i INF.03
...