🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.java
13 messages
13 total messages Started by Piotr Rezmer Fri, 23 Nov 2012 00:20
jquery callback i pętla
#153641
Author: Piotr Rezmer
Date: Fri, 23 Nov 2012 00:20
32 lines
1711 bytes
Witam

Chcialbym osiągnąć następujący efekt: Wczytywanie obiektu JSON za pomocą 
asynchronicznejgo .getJSON(). Wczytywanie powinno się odbywać 
cyklicznie, zaraz po zakończeniu wczytywania poprzedniego obiektu. Czy 
mogę umieścić ponowne wywołanie funkcji w callbacku? Czyli cos takiego

	function parseResponse( data ) {
			... // process data
			getJsonInLoop();
}
	function getJsonInLoop() {
		$.getJSON("/embedded/WaitForChanges",
	  {
	    extension: "1103",
	    changedate: lastchange,
	    tagmode: "any",
	    format: "json"
	  },
	  function(data) {
	  	parseResponse( data );
	  });
	}

Nie nastąpi po pewnym czasie stack overflow?



-- 
pozdrawiam
Piotr
XLR250&bmw_f650_dakar
Re: jquery callback i pętla
#153655
Author: Arivald
Date: Fri, 23 Nov 2012 07:43
45 lines
2573 bytes
W dniu 2012-11-23 01:20, Piotr Rezmer pisze:
> Witam
>
> Chcialbym osiągnąć następujący efekt: Wczytywanie obiektu JSON za pomocą
> asynchronicznejgo .getJSON(). Wczytywanie powinno się odbywać
> cyklicznie, zaraz po zakończeniu wczytywania poprzedniego obiektu. Czy
> mogę umieścić ponowne wywołanie funkcji w callbacku? Czyli cos takiego
>
>      function parseResponse( data ) {
>              ... // process data
>              getJsonInLoop();
> }
>      function getJsonInLoop() {
>          $.getJSON("/embedded/WaitForChanges",
>        {
>          extension: "1103",
>          changedate: lastchange,
>          tagmode: "any",
>          format: "json"
>        },
>        function(data) {
>            parseResponse( data );
>        });
>      }
>
> Nie nastąpi po pewnym czasie stack overflow?
>

To chyba zależy od implementacji, od tego jak jest realizowana 
asynchroniczność getJSON.

Ja do podobnego efektu, bez jquery, używałem SetTimeout() z bardzo 
krótkim czasem.
Tylko jako funkcji do SetTimeout() nie podawaj stringa ani funkci 
anonimowej tworzonej ad-hoc, bo to może powodować wyciek pamięci.

btw "success-handler" dla getJSON tez lepiej żeby to nie była funkcja 
anonimowa. Bo one też tworzona jest ad-hoc, za każdym razem nowa kopia.

Lepiej stworzyć sobie obiekt który się tym całym taskiem zajmuje, i 
zarówno funkcje timeouta jak i success-handler zdefiniować w obiekcie. 
Wtedy jedna i ta same kopia będzie używana.

-- 
Arivald
Re: jquery callback i pętla
#153656
Author: Piotr Rezmer
Date: Fri, 23 Nov 2012 19:00
39 lines
1878 bytes
Arivald pisze:

> btw "success-handler" dla getJSON tez lepiej żeby to nie była funkcja
> anonimowa. Bo one też tworzona jest ad-hoc, za każdym razem nowa kopia.

Próbowałem przekazać zewnętrzną nazwaną metodę ale nie łyka :(


> Lepiej stworzyć sobie obiekt który się tym całym taskiem zajmuje, i
> zarówno funkcje timeouta jak i success-handler zdefiniować w obiekcie.
> Wtedy jedna i ta same kopia będzie używana.

Coś takiego?:

class LoadManager() {

private boolean loadCompleted;

public run() {
   loadCompleted = false;
   while (!notInterrupted) {
     getJSON(<>
         function( data, result ) {
		loadCompleted = true;
         }
	);
     while (!loadCompleted) {
         setTimeout(50 ms)  <-- taki "sleep"
     }
   }
}
}



-- 
pozdrawiam
Piotr
XLR250&bmw_f650_dakar
Re: jquery callback i pętla
#153658
Author: Arivald
Date: Sat, 24 Nov 2012 06:51
75 lines
2888 bytes
W dniu 2012-11-23 20:00, Piotr Rezmer pisze:
> Arivald pisze:
>
>> btw "success-handler" dla getJSON tez lepiej żeby to nie była funkcja
>> anonimowa. Bo one też tworzona jest ad-hoc, za każdym razem nowa kopia.
>
> Próbowałem przekazać zewnętrzną nazwaną metodę ale nie łyka :(
>
>
>> Lepiej stworzyć sobie obiekt który się tym całym taskiem zajmuje, i
>> zarówno funkcje timeouta jak i success-handler zdefiniować w obiekcie.
>> Wtedy jedna i ta same kopia będzie używana.
>
> Coś takiego?:
>
> class LoadManager() {
>
> private boolean loadCompleted;
>
> public run() {
>    loadCompleted = false;
>    while (!notInterrupted) {
>      getJSON(<>
>          function( data, result ) {
>          loadCompleted = true;
>          }
>      );
>      while (!loadCompleted) {
>          setTimeout(50 ms)  <-- taki "sleep"
>      }
>    }
> }
> }
>

Może to głupie pytanie, ale to ma być Java czy JavaScript? Bo poprzedni 
przykład wyglądał na JavaScript, zaś ten wygląda na Javę.

Zarówno jeśli chodzi o SetTimeout() jak i "stworzyć obiekt" miałem na 
myśli JavaScript.

Com mniej więcej tak:

var JsonLoader = {
   done: false,

   function makeAjaxRequest() {
     $.getJSON("/embedded/WaitForChanges", {
         extension: "1103",
         changedate: lastchange,
         tagmode: "any",
         format: "json"
       },
       this.processJSON
     );
   },

   function processJSON(data) {
     .....
     done = .....
     if (!done) SetTimeOut(this.makeAjaxRequest, 1);
   }

   function start() {
     done = false;
     SetTimeOut(this.makeAjaxRequest, 1);
   },

   function stop() {
     done = true;
   }
}

-- 
Arivald
Re: jquery callback i pętla
#153660
Author: Piotr Rezmer
Date: Sat, 24 Nov 2012 09:47
43 lines
2145 bytes
Arivald pisze:

>
> Może to głupie pytanie, ale to ma być Java czy JavaScript? Bo poprzedni
> przykład wyglądał na JavaScript, zaś ten wygląda na Javę.

Sorry, nie bardzo trawię swobodę w Javascripcie i dlatego napisałek 
pseudokod w javie :)
> Com mniej więcej tak:
>
> var JsonLoader = {
>    done: false,
>
>    function makeAjaxRequest() {
>      $.getJSON("/embedded/WaitForChanges", {
>          extension: "1103",
>          changedate: lastchange,
>          tagmode: "any",
>          format: "json"
>        },
>        this.processJSON
>      );
>    },
>
>    function processJSON(data) {
>      .....
>      done = .....
>      if (!done) SetTimeOut(this.makeAjaxRequest, 1);
>    }
>
>    function start() {
>      done = false;
>      SetTimeOut(this.makeAjaxRequest, 1);
>    },

Jasne. Czyli w processJSON() zwalniamy stos w jQuery. Rozumiem, że 
implementacja SetTimeout() jest bezpieczna i nie prowadzi do wyczerpania 
zasobów?

-- 
pozdrawiam
Piotr
XLR250&bmw_f650_dakar
Re: jquery callback i pętla
#153668
Author: Arivald
Date: Sat, 24 Nov 2012 12:03
57 lines
3061 bytes
W dniu 2012-11-24 10:47, Piotr Rezmer pisze:
> Arivald pisze:
>
>>
>> Może to głupie pytanie, ale to ma być Java czy JavaScript? Bo poprzedni
>> przykład wyglądał na JavaScript, zaś ten wygląda na Javę.
>
> Sorry, nie bardzo trawię swobodę w Javascripcie i dlatego napisałek
> pseudokod w javie :)
>> Com mniej więcej tak:
>>
>> var JsonLoader = {
>>    done: false,
>>
>>    function makeAjaxRequest() {
>>      $.getJSON("/embedded/WaitForChanges", {
>>          extension: "1103",
>>          changedate: lastchange,
>>          tagmode: "any",
>>          format: "json"
>>        },
>>        this.processJSON
>>      );
>>    },
>>
>>    function processJSON(data) {
>>      .....
>>      done = .....
>>      if (!done) SetTimeOut(this.makeAjaxRequest, 1);
>>    }
>>
>>    function start() {
>>      done = false;
>>      SetTimeOut(this.makeAjaxRequest, 1);
>>    },
>
> Jasne. Czyli w processJSON() zwalniamy stos w jQuery. Rozumiem, że
> implementacja SetTimeout() jest bezpieczna i nie prowadzi do wyczerpania
> zasobów?
>

Działa jak każdy timer. Wywołanie SetTimeout nie blokuje stosu, a 
wywołanie callbacka timera (this.makeAjaxRequest) startuje niejako od 
zerowego stosu.

Bardzo możliwe że asynchroniczne wywołanie ajaxowe ($.getJSON) też 
zaczyna zawsze od pustego stosu... ale tu nie jestem pewien.

W Twoim oryginalnym kodzie dodatkowym problemem mogła być anonimowe 
funkcja. W JavaScripcie jest coś takiego jak "closure", tzn przy 
wywołaniu funkcji jej otoczenie, kontekst wywołania może być przenoszony 
aby był dostępny z funkcji. Także jeśli funkcja jest wołana 
asynchronicznie. I teraz przy kolejnych wywołaniach $.getJSON tworzysz 
kolejno anonimową funkcją, kolejny closure który pamięta też poprzednie...

-- 
Arivald
Re: jquery callback i pętla
#153659
Author: William Bonawentura
Date: Mon, 26 Nov 2012 06:25
4 lines
1408 bytes
> Sorry, nie bardzo trawię swobodę w Javascripcie i dlatego napisałek 
> pseudokod w javie :)

    Skoro znasz Javę to nie pisz wprost w JS tylko przesiądź się na GWT. 
Re: jquery callback i pętla
#153654
Author: Piotr Rezmer
Date: Wed, 16 Jan 2013 18:12
42 lines
2059 bytes
Arivald pisze:

>
>    function makeAjaxRequest() {
>      $.getJSON("/embedded/WaitForChanges", {
>          extension: "1103",
>          changedate: lastchange,
>          tagmode: "any",
>          format: "json"
>        },
>        this.processJSON
>      );
>    },
>


Tutaj mały zonk: $.getJSON() słabo się sprawdza do sprawdzania eventów, 
gdyż korzysta z metody GET. W ten sposób tylko pierwsze wywołanie trafia 
do serwera, pozostałe są cacheowane i jest brak prawdziwej komunikacji z 
serwerem.
Warto dodać do pliku .js nową rozszerzenie jQuery o POST:

  	jQuery.extend({
  	   postJSON: function( url, data, callback) {
  	      return jQuery.post(url, data, callback, "json");
  	   }
  	});


Wtedy wygląda to:

		makeAjaxRequest: function() {
			$.postJSON(AppContext+"/WaitForChanges",
			....

Inaczej widać "gonitwę" w Taskmanagerze dla przeglądarki.


-- 
pozdrawiam
Piotr
XLR250&bmw_f650_dakar
Re: jquery callback i pętla
#153662
Author: Arivald
Date: Wed, 16 Jan 2013 18:30
51 lines
2467 bytes
W dniu 2013-01-16 19:12, Piotr Rezmer pisze:
> Arivald pisze:
>
>>
>>    function makeAjaxRequest() {
>>      $.getJSON("/embedded/WaitForChanges", {
>>          extension: "1103",
>>          changedate: lastchange,
>>          tagmode: "any",
>>          format: "json"
>>        },
>>        this.processJSON
>>      );
>>    },
>>
>
>
> Tutaj mały zonk: $.getJSON() słabo się sprawdza do sprawdzania eventów,
> gdyż korzysta z metody GET. W ten sposób tylko pierwsze wywołanie trafia
> do serwera, pozostałe są cacheowane i jest brak prawdziwej komunikacji z
> serwerem.

Standartowy problem, standardowe obejście: dodaj do urla parametr o 
przypadkowej wartości (innej dla każdego wywołania), np:

       $.getJSON("/embedded/WaitForChanges?random=gfdbssd", {

A jeszcze lepiej ustawić odpowiednie warunki keszowania dla tego jsona 
na serwerze.


Albo może globalnie wyłączyć cache:

$.ajaxSetup({
   cache: false
});


Gdybyś używał $.ajax({ ... to mógł być zabronić keszowania bezpośrednio...

$.ajax({
   cache: false,
   dataType: "json",
   url: ...,
   data: ...,
   success: ...
});


-- 
Arivald
Re: jquery callback i pętla
#153663
Author: Arivald
Date: Wed, 16 Jan 2013 18:35
39 lines
2453 bytes
W dniu 2013-01-16 19:30, Arivald pisze:
> W dniu 2013-01-16 19:12, Piotr Rezmer pisze:
>> Arivald pisze:
>>
>>>
>>>    function makeAjaxRequest() {
>>>      $.getJSON("/embedded/WaitForChanges", {
>>>          extension: "1103",
>>>          changedate: lastchange,
>>>          tagmode: "any",
>>>          format: "json"
>>>        },
>>>        this.processJSON
>>>      );
>>>    },
>>>
>>
>>
>> Tutaj mały zonk: $.getJSON() słabo się sprawdza do sprawdzania eventów,
>> gdyż korzysta z metody GET. W ten sposób tylko pierwsze wywołanie trafia
>> do serwera, pozostałe są cacheowane i jest brak prawdziwej komunikacji z
>> serwerem.
>
> Standartowy problem, standardowe obejście: dodaj do urla parametr o
> przypadkowej wartości (innej dla każdego wywołania), np:
>
>        $.getJSON("/embedded/WaitForChanges?random=gfdbssd", {
>

A dokładniej:

$.getJSON("/embedded/WaitForChanges?random=" + 
Math.random().toString(36).substr(2), {

...czyli generujemy przypadkowy numer, konwersja do stringa o bazie 36 
(a-z0-9), i obcinamy pierwsze dwa znaki, czyli "0.".

-- 
Arivald
Re: jquery callback i pętla
#153664
Author: Piotr Rezmer
Date: Fri, 18 Jan 2013 09:13
27 lines
2269 bytes
Arivald pisze:

> A dokładniej:
>
> $.getJSON("/embedded/WaitForChanges?random=" +
> Math.random().toString(36).substr(2), {
>
> ...czyli generujemy przypadkowy numer, konwersja do stringa o bazie 36
> (a-z0-9), i obcinamy pierwsze dwa znaki, czyli "0.".

Ale przyznasz, że wygląda to choro? Używałem kiedyś dodawania zmiennego 
parametru, ale generalnie jestem przeciw. Podejrzewam, że wynika to z 
niedopasowania filozofii http i zwykłej komunikacji. Myślę, że 
najbardziej eleganckie rozwiązanie to deaktywowanie cache w określonych 
operacjach. Globalne wyłączanie cache byłoby raczej wylaniem dziecka z 
kąpielą.
Na razie opieram się o postJSON() ale też nie jest to najbardziej 
zgrabne rozwiązanie. Tak naprawdę getEvent() jest raczej getterem niż 
setterem i moje bieżące rozwiązanie oparte na setterze nie jest 
intuicyjne. Jak się da, w niektórych sytuacja zamienię postJSON() na ajax().
Po prostu trudno cache'ować POST bo prowadziłoby to do niespójnego stanu 
aplikacji.

-- 
pozdrawiam
Piotr
XLR250&bmw_f650_dakar
Re: jquery callback i pętla
#153661
Author: Arivald
Date: Fri, 18 Jan 2013 10:21
34 lines
2473 bytes
W dniu 2013-01-18 10:13, Piotr Rezmer pisze:
> Arivald pisze:
>
>> A dokładniej:
>>
>> $.getJSON("/embedded/WaitForChanges?random=" +
>> Math.random().toString(36).substr(2), {
>>
>> ...czyli generujemy przypadkowy numer, konwersja do stringa o bazie 36
>> (a-z0-9), i obcinamy pierwsze dwa znaki, czyli "0.".
>
> Ale przyznasz, że wygląda to choro?

Owszem. Dlatego najwłaściwszym rozwiązaniem jest zmiana na serwerze, 
żeby dla tego skryptu/apletu generującego JSON określał właściwe warunki 
keszowania. Bo tylko serwer jest w stanie powiedzieć czy trzeba czy nie 
trzeba keszować, przegladarka (i pośrednie proxy) się tylko dostowowują.

Jeśli możesz to zrobić (Twój serwer) to zrób.

A jeśli się nie da zmienić serwera, to się używa takich protez.


> Na razie opieram się o postJSON() ale też nie jest to najbardziej
> zgrabne rozwiązanie. Tak naprawdę getEvent() jest raczej getterem niż
> setterem i moje bieżące rozwiązanie oparte na setterze nie jest
> intuicyjne. Jak się da, w niektórych sytuacja zamienię postJSON() na
> ajax().
> Po prostu trudno cache'ować POST bo prowadziłoby to do niespójnego stanu
> aplikacji.
>

-- 
Arivald
Re: jquery callback i pętla
#153666
Author: Tomek Kańka
Date: Fri, 18 Jan 2013 10:27
13 lines
1439 bytes
Piotr Rezmer <p.r@bezbzdur.pl> napisał(a)

> Po prostu trudno cache'ować POST bo prowadziłoby to do niespójnego stanu 
> aplikacji.
>


Uwaga na marginesie. W iOS6 Safari zaczęło cache-ować POSTy. Co gorsza
Apple ma po swojej stronie jakieś RFC. Nie zgłębiałem tematu, bo mnie to
nie spotkało, ale zalecam ostrożność.

-- 
Tomek 
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads