• 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

Object Storage Arubacloud
0 głosów
149 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 Ekspert (344,860 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 Ekspert (344,860 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 Ekspert (344,860 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,510 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 Ekspert (344,860 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ź 423 wizyt
pytanie zadane 7 grudnia 2018 w JavaScript przez DragonCoder Nałogowiec (36,500 p.)
0 głosów
1 odpowiedź 204 wizyt
+1 głos
1 odpowiedź 393 wizyt

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,958 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...