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

question-closed Deklaracja funkcji wykonuje funkcje przy użyciu XMLHttpRequest

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
217 wizyt
pytanie zadane 19 sierpnia 2019 w JavaScript przez Bartłomiej Bolesta Obywatel (1,630 p.)
zamknięte 3 września 2019 przez Bartłomiej Bolesta

Chociaż nie jestem pewien czy temat dobrze odzwierciedla problem. Sporo mi zajęło przeszukiwanie kodu, gdzie jest problem i zminimalizowałem go (chyba) już do samego problemu:

var newValue = 0;	
var addConst = 0;

function start() {
	const dataFromLS = JSON.parse(localStorage.getItem('valuesInStore'));	
	newValue += addConst;

	console.log(document.getElementById("show").innerHTML = Math.round(newValue) + parseInt(dataFromLS[0]));
	document.getElementById("show").innerHTML = Math.round(newValue) + parseInt(dataFromLS[0]);
	
	setTimeout(start, 1000);
};	
	
document.addEventListener("DOMContentLoaded", function(){
	var xmlhttp = new XMLHttpRequest();
		xmlhttp.onreadystatechange = function() {
			if (this.readyState == 4 && this.status == 200) {
				var values = JSON.parse(this.responseText);

				console.log(values[0]);
				const valuesInStore = {0: values[0], 1: values[1], 2: values[2], 3: values[3], 4: values[4]};
				localStorage.setItem('valuesInStore', JSON.stringify(valuesInStore)); 
			}	
		};
		xmlhttp.open("GET", "../phpfiles/ajaxphpfiles/r_array.php", true);
		xmlhttp.send();
});

document.addEventListener("DOMContentLoaded", function(){
	const dataFromLSB = JSON.parse(localStorage.getItem('valuesInStore2'));
	
	if(dataFromLSB[1] == 0)	{
		addConst = 0;			
	} else {
		addConst = /*jakiś długi wzór*/
	}	
	start();	
});

 

1) Deklaruję funkcję start.

2) Używam XMLHttpRequest do pobrania zmiennych z php, które pochodzą z bazy danych.

3) Ponownie używam XMLHttpRequest, do pobrania zmiennych z php, które również pochodzą z bazy danych (już nie wrzucałem kodu, aby było bardziej czytelne, a i tak nie jest istotny).

4)  Tworzę anonimową funkcję do której pobieram dane z pkt 3 i obliczam na ich podstawie wartość, którą użyję w funkcji "start".

5) Wywołuję funkcję "start".

6) Funkcja "start" pobiera dane z pkt 2 i w pętli co sekundę inkrementuje wartość z pkt 4 by następnie wyświelić na stronie/w consoli ową wartość, powiększoną o wartość z punktu trzeciego.

np.
dataFromLS[0] = 1000;

addConst = 0,5;

Więc co sekundę stan (uwzględniając zaokrąglanie) będzie wyglądał tak: 1000, 1000, 1001, 1001, 1002 itd.

W konsoli powinno to wyglądać tak:

1000 scripts_template.js:20 (console.log z pkt 2)

2 1001 scripts_template.js:8 (console.logi z pkt 6)
2 1002 scripts_template.js:8
2 1003 scripts_template.js:8
2 1004 scripts_template.js:8

A tymczasem, przed tym pojawia się jeszcze jedna linijka:

995 scripts_template.js:8 

Ta linijka, pokazuje wartość z poprzedniego odświeżenia strony, więc gdyteraz odświeżę stronę, to w tym miejscu pokaże:

1000 scripts_template.js:8

I teraz problem polega na tym, że z używając inner.html pierwsza wartość po odświeżeniu strony pojawia się np. te 995, a potem (w zależności jak dużo czasu minęło) skacze np. do 1200 i potem dopiero normalnie 1201, 1202 itd.

Wygląda to tak, jakby funkcja start przy pierwszym wczytaniu pliku js wykonywała tą funkcję, lub wykonywała ją przed pobraniem danych w pkt 2. Zapewne przez synchorniczne pobranie. I nie mogę znaleźć odpowiedzi jak opóźnić wykonanie do czasu pobrania nowych wartości. Nie takiej, która by zadziałała i co ważniejsze, bym zrozumiał, a nie tylko przeklepał kod.

komentarz zamknięcia: rozwiązano
1
komentarz 19 sierpnia 2019 przez adrian17 Mentor (351,100 p.)

Na szybko na oko, więc tylko komentarz:

Zapewne przez synchorniczne pobranie

asynchroniczne.

nie mogę znaleźć odpowiedzi jak opóźnić wykonanie do czasu pobrania nowych wartości

Po prostu wywołaj start() po obsłużeniu zapytania w handlerze.

komentarz 20 sierpnia 2019 przez Bartłomiej Bolesta Obywatel (1,630 p.)

Po prostu wywołaj start() po obsłużeniu zapytania w handlerze.

Jakby mi wyszło to bym po prostu tak zrobił i nie byłoby tematu.

1
komentarz 20 sierpnia 2019 przez adrian17 Mentor (351,100 p.)
To pokaż co spróbowałeś i czemu nie wyszło, bo nie wiem dlaczego by to nie miało działać.
komentarz 20 sierpnia 2019 przez Bartłomiej Bolesta Obywatel (1,630 p.)
Nie skopiuje Ci teraz kodu, bo co nie wychodziło to czyściłem do punktu wyjścia.
1
komentarz 20 sierpnia 2019 przez adrian17 Mentor (351,100 p.)

W każdym razie...

var request = new XMLHttpRequest();
request.onload = function() {
    // ... parsowanie
    start();

To wciąż na intuicję brzmi jak bezpośrednie rozwiązanie.

komentarz 26 sierpnia 2019 przez Bartłomiej Bolesta Obywatel (1,630 p.)
Wybacz, że dopiero, ale nie było czasu przysiąść. Nie ma różnicy, ale dałem z onloadem i przeszło. Wróciłem do starego i też przeszło. Nie wiem co się działo wtedy, ale gdy funkcję starałem się m.in. po prostu wywoływać tak jak wyżej, to nie widziało jej (nawet wyszarzało deklarację), a teraz widzi. Nie wyłączałem wtedy przeglądarki, xamppa, więc może były jakieś naleciałości i nie współgrało. Na przyszłość, muszę wpierw zacząć wszystko restartować. Potem szukać, gdzie leży problem. Dzięki.

1 odpowiedź

0 głosów
odpowiedź 19 sierpnia 2019 przez Tomek Sochacki Ekspert (227,490 p.)

Generalnie z Twojego opisu widzę takie coś:

  1. pobieram dane X z serwera
  2. pobieram dane Y z serwera
  3. mając X i Y coś z tymi danymi robię

Jeśli dobrze to rozumiem to ja bym wziął tu jakąś libkę do owinięcia tego w promise, np. axios - szkoda czasu na robienie tego samemu. Następnie zrobiłbym 2 strzały i zrobił np. Promise.all aby mieć pewność, że będę pracował dopiero gdy przyjdą oba responsy.

Ale jeśli to dane, które nie potrzebują siebie wzajemnie, a tak wynika z treści, to dlaczego nie pobierasz ich w jednym requescie? Czy na pewno warto dodawać narzut czasu na otworzenie nowego połączenia, nie lepiej w back-endzie zrobić dwa strzały do bazy i gdy oba przyjdą to wtedy zrobić jedną zwrotkę? Ewentualnie kwestia timeoutów itp. ale to już osobny temat.

A jeśli to jakieś większe dane to w takich przypadkach najczęściej pracuję z SSE, gdzie na . froncie zapinam się np. przy użyciu rxjs na kolejne streamy danych.

1
komentarz 20 sierpnia 2019 przez adrian17 Mentor (351,100 p.)

Jeśli dobrze to rozumiem to ja bym wziął tu jakąś libkę do owinięcia tego w promise, np. axios

(fetch?)

komentarz 20 sierpnia 2019 przez Bartłomiej Bolesta Obywatel (1,630 p.)

Jeśli dobrze to rozumiem to ja bym wziął tu jakąś libkę do owinięcia tego w promise, np. axios - szkoda czasu na robienie tego samemu.

Ale tu chodzi właśnie o robienie samemu, żeby się nauczyć i rozumieć, a nie omijać problem czymś co zrobi robotę za mnie.

Ale jeśli to dane, które nie potrzebują siebie wzajemnie, a tak wynika z treści, to dlaczego nie pobierasz ich w jednym requescie?

 

Nie dokopałem się do metody, gdzie mogę to zrobić jednym sposobem. Chyba, że chodzi Ci oto, aby wszystko było w jednym pliku:

xmlhttp.open("GET", "../phpfiles/ajaxphpfiles/r_array.php", true);

I przy odebraniu, tylko je rozdzielić? To tak robię gdzieniegdzie, ale w tym przypadku, dane z obu plików używam i będę używał nie tylko tutaj, a akurat w tym skrypcie zdarzyło się, że potrzebne są oba. Musiałbym je potem wszędzie rozdzielać. Także nie ma sensu.

Podobne pytania

0 głosów
1 odpowiedź 621 wizyt
pytanie zadane 7 grudnia 2018 w JavaScript przez DragonCoder Nałogowiec (36,500 p.)
0 głosów
1 odpowiedź 345 wizyt
+1 głos
1 odpowiedź 749 wizyt

93,187 zapytań

142,201 odpowiedzi

322,012 komentarzy

62,514 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 2127p. - dia-Chann
  2. 2092p. - Łukasz Piwowar
  3. 2079p. - Łukasz Eckert
  4. 2037p. - Tomasz Bielak
  5. 2006p. - Michal Drewniak
  6. 2006p. - rucin93
  7. 2005p. - Łukasz Siedlecki
  8. 1964p. - CC PL
  9. 1946p. - Adrian Wieprzkowicz
  10. 1901p. - Mikbac
  11. 1744p. - rafalszastok
  12. 1734p. - Anonim 3619784
  13. 1586p. - Dawid128
  14. 1520p. - Marcin Putra
  15. 1480p. - ssynowiec
Szczegóły i pełne wyniki

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...