Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [JavaScript] Wyświetlanie innego obrazka po płynnym zniknięciu poprzedniego
SmokAnalog
post 25.04.2018, 10:48:49
Post #1





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Witajcie,

mam takie pytanko z kategorii "jak to elegancko zrobić?". Załóżmy, że robimy sobie własny skrypt galerii, gdzie wyświetlamy duże i ciężkie obrazki. Widoczny jest tylko jeden obrazek naraz. Po kliknięciu na przycisk, aktualny obrazek płynnie znika i po jego zniknięciu płynnie pojawia się kolejny.

Problem polega na tym, żeby ładnie zsynchronizować ładowanie kolejnego obrazka i animację znikania. Naiwna implementacja mogłaby zacząć ładować obrazek B w momencie, kiedy obrazek A już zniknął. Tracimy jednak w ten sposób cenny czas i każemy użytkownikowi czekać.

Jeszcze gorsza implementacja ładowałaby obrazek zaraz po kliknięciu na przycisk i w momencie załadowania obrazka B, podmieniałaby obrazek A na obrazek B. Efekt byłby taki, że - w zależności od tego jak to dokładnie zaimplementujemy - albo animacja znikania się utnie, albo (jeszcze gorzej) znikający obrazek zamieni się w obrazek B i znowu pojawi. Fujka i amatorszczyzna.

Kiedyś robiłem to tak, że ustawiałem dwa callbacki - jeden na zakończenie animacji i jeden na załadowanie obrazka. Każdy z tych callbacków dodawał do pewnej zmiennej 1 i, jeżeli ta zmienna wynosi 2, uruchamiał animację pojawiania się obrazka B. Przy wartości 2 było wiadomo, że animacja znikania się skończyła i obrazek jest gotowy.

Dzisiaj mamy jednak do dyspozycji Promise. I moje pytanie jest takie - czy Promise.all() to idealne rozwiązanie tego problemu na dzień dzisiejszy? Pomyślałem o takim rozwiązaniu (trochę pseudokod):

[JAVASCRIPT] pobierz, plaintext
  1. Promise.all([fadedOutFinishedPromise, newImageLoadedPromise]).then(fadeIn);
[JAVASCRIPT] pobierz, plaintext


Podsumowując: jak Wy byście rozwiązali ten problem? Czy lubicie i używacie Promise i Promise.all()? I pytanie dodatkowe: jeśli animacja fade in i fade out dzieje się w CSS, czy istnieje lepszy sposób na określenie jej zakończenia niż setTimeout() ustawiony na czas trwania animacji?
Go to the top of the page
+Quote Post
gitbejbe
post 25.04.2018, 11:52:06
Post #2





Grupa: Zarejestrowani
Postów: 515
Pomógł: 63
Dołączył: 27.08.2012

Ostrzeżenie: (0%)
-----


Promise to tylko handler dla pewnych akcji/zdarzeń, jeśli uważasz że akurat taki sposób Ci pasuje to dlaczego nie ? Po za tym Twój problem to nie jest fakt jakiego handlera użyjesz, chcesz przecież osiągnąć płynną animację przewijania obrazków.
Jeśli obrazki doładowujesz, to raczej nie uda Ci się wyeliminować tego problemu, ewentualnie możesz go zmniejszyć. Pierwsze co mi przychodzi na myśl, to ładowanie na raz nie jednego - obecnego, obrazka a np 2, czyli obecny i kolejny.
Można tutaj zastosować proste kolejkowanie, aby ten główny ładował się jako pierwszy co jest pożądane, a po tym niech ładuje się odrazu kolejny i czeka na wyświetlenie. Można w ten sposób ładowac więcej grafik w tle, podaje tylko przypkład. Pozostaje fakt spamowania przewijania przez użytkownika, można trochę to ukrócić i dać trochę więcej czasu na ładowanie poprzez blokowanie przewijania na czas animacji - jednak nadal tutaj zalezy wszystko od rozmiaru obrazka/szybkości łącza. Wydaje mi się jednak że to dobra droga.
Go to the top of the page
+Quote Post
SmokAnalog
post 25.04.2018, 13:33:53
Post #3





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Cytat(gitbejbe @ 25.04.2018, 12:52:06 ) *
Po za tym Twój problem to nie jest fakt jakiego handlera użyjesz, chcesz przecież osiągnąć płynną animację przewijania obrazków.

Nie przewijania, tylko znikania i pojawiania się. To zmienia tutaj strategię działania, bo w przewijaniu nie może być mowy o odczekaniu, a w pojawianiu się owszem.

Cytat(gitbejbe @ 25.04.2018, 12:52:06 ) *
Pierwsze co mi przychodzi na myśl, to ładowanie na raz nie jednego - obecnego, obrazka a np 2, czyli obecny i kolejny.

To jest oczywiście popularne rozwiązanie, ale celowo podkreśliłem, że obrazki będą duże. Z szacunku dla łącza mobilnego nie chcę zmuszać użytkownika do ładowania np. 1 MB w postaci obrazka, którego on wcale nie chce oglądać.

Cytat(gitbejbe @ 25.04.2018, 12:52:06 ) *
Pozostaje fakt spamowania przewijania przez użytkownika, można trochę to ukrócić i dać trochę więcej czasu na ładowanie poprzez blokowanie przewijania na czas animacji.

Powiem Ci, że jako użytkownik bym się wkurzał, gdyby mi blokowano możliwość przewijania, kiedy obrazek się jeszcze nie doładował. Jest to kiepski user experience, bo przewinięcie galerii będzie uciążliwe. Jak już to bym wyświetlał animację ładowania na slajdzie. Ale, jak już mówiłem, nie o przewijanie tu chodzi smile.gif
Go to the top of the page
+Quote Post
gitbejbe
post 25.04.2018, 23:39:49
Post #4





Grupa: Zarejestrowani
Postów: 515
Pomógł: 63
Dołączył: 27.08.2012

Ostrzeżenie: (0%)
-----


Wiem o co Ci chodzi, użyłem tylko niewłaściwego słowa. Cały czas miałem na myśli pojawianie i znikanie.

Cytat
To jest oczywiście popularne rozwiązanie, ale celowo podkreśliłem, że obrazki będą duże. Z szacunku dla łącza mobilnego nie chcę zmuszać użytkownika do ładowania np. 1 MB w postaci obrazka, którego on wcale nie chce oglądać.


z szacunku do łącza ? Nie chce do niczego ciebie przekonywać, ale wydaje mi się przesadzasz. Po 1 nikt nie wnika w to że galeria zdjęć generuje transfer - co innego filmy(i uprzedzam że nie trafia do nie argument że Ty akurat na to może zwracasz uwagę). po 2 to jak inaczej chcesz to zrobić ? Albo godzisz się na tranfer danych, albo optymalizujesz. Poprzez optymalizacje, możesz np ten plik graficzny wyświetlać w 2 wersjach - pierwszy w słabej rozdzielczości ale za to pojawia się niemal natychmiast, a drugi w org jakości który się w międzyczasie doładowuje i zastępuje ten pierwszy (tak np robi galeria google). Wybór należy do Ciebie

Cytat
Powiem Ci, że jako użytkownik bym się wkurzał, gdyby mi blokowano możliwość przewijania, kiedy obrazek się jeszcze nie doładował. Jest to kiepski user experience, bo przewinięcie galerii będzie uciążliwe. Jak już to bym wyświetlał animację ładowania na slajdzie. Ale, jak już mówiłem, nie o przewijanie tu chodzi


tutaj znowu gra słów bo nie chodziło mi o jakieś scrollowanie - wyjaśniłem na początku. Tak więc dalej podtrzymuje to co napisałem, tylko nie pod kątem "przewijania" a zwykłego przełączania zdjęć. Blokowanie na czas animacji nie jest uciążliwe a nawet wręcz rozsądne/pożądane - zapobiegasz przypadkowemu double click
Go to the top of the page
+Quote Post
SmokAnalog
post 26.04.2018, 17:30:41
Post #5





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Cytat(gitbejbe @ 26.04.2018, 00:39:49 ) *
Po 1 nikt nie wnika w to że galeria zdjęć generuje transfer - co innego filmy(i uprzedzam że nie trafia do nie argument że Ty akurat na to może zwracasz uwagę).

Co to znaczy, że nikt nie zwraca? Przepytałeś cały świat web developerów? Mnóstwo programistów zwraca uwagę na transfer dużych obrazów.

Cytat(gitbejbe @ 26.04.2018, 00:39:49 ) *
Poprzez optymalizacje, możesz np ten plik graficzny wyświetlać w 2 wersjach - pierwszy w słabej rozdzielczości ale za to pojawia się niemal natychmiast, a drugi w org jakości który się w międzyczasie doładowuje i zastępuje ten pierwszy (tak np robi galeria google).

Owszem, tylko że Google wyświetla malutkie miniatury. Poza tym Google to narzędzie, a nie wizytówka, która ma wyglądać estetycznie. Pokazywanie zamazywanych obrazów to straszna wiocha.

Cytat(gitbejbe @ 26.04.2018, 00:39:49 ) *
Blokowanie na czas animacji nie jest uciążliwe a nawet wręcz rozsądne/pożądane - zapobiegasz przypadkowemu double click

Ten argument jest już zupełnie na siłę i nic nie wnosi.
Go to the top of the page
+Quote Post
gitbejbe
post 26.04.2018, 22:26:56
Post #6





Grupa: Zarejestrowani
Postów: 515
Pomógł: 63
Dołączył: 27.08.2012

Ostrzeżenie: (0%)
-----


dobra bo zaczynasz gwiazdorzyć

Podałem Tobie trafne rozwiązania, jeśli nie potrafisz tego ogarnąć to na koniec z czystej uprzejmości dla potomnych napisze to ostatni raz

ładowanie w tle. Po załadowaniu obecnie wyświetlanego obrazka, w tle ładuje się następny i czeka. Jeśli użytkownik nie zmienia szybko obrazków, to animacja będzie płynna. W każdym razie i tak należy zastosować jakiś loader w razie co.
Jeśli jest takie ogromne parcie aby jednak tego loadera nie było, można przerobić trochę kolejkę aby najpierw wczytywał się kolejny obrazek w słabszej rozdzielczości a następnie w lepszej. Nadal mamy dzięki temu zachowaną płynność, nie ma loadera, kossztem jedynie tego, że jeśli użytkownik szybko będzie zmieniał obrazy, to przez chwilę widzieć będzie słabszą jakość. To jak niskiej jakości będzie ewentualny doczytywany obrazek zależy już tylko od programisty i nie musi to wyglądać jak wiocha w bladym rozumieniu autora, który uważa że skoro google nie wygląda jak wizytówka to nie można opierać się na jego rozwiązaniach - dałeś radę.

a i przegapiłem jjedno pytanie
Cytat
czy istnieje lepszy sposób na określenie jej zakończenia niż setTimeout() ustawiony na czas trwania animacji?


setTimeout to nie jest sposób, tylko dramat spowodowany brakiem wiedzy i lenistwem. Takie rzeczy przechwytuje się w zdarzeniach, nawet z łaski swojej wkleję Tobie mój urywek kodu do analizy:

  1. transitionEvent: function(){
  2. var
  3. element = document.createElement('element'),
  4. transitions = {
  5. 'transition' :'transitionend',
  6. 'OTransition' :'oTransitionEnd',
  7. 'MozTransition' :'transitionend',
  8. 'WebkitTransition' :'webkitTransitionEnd'
  9. },
  10. transition
  11. ;
  12. for(transition in transitions){
  13. if( element.style[transition] !== undefined ){
  14. return transitions[transition];
  15. }
  16. }
  17.  
  18. return false;
  19. }();
  20.  
  21. $element.on(transitionEvent, function(event){
  22. ... koniec animacji
  23. });
  24.  
  25.  
  26. $element.addClass('fade-in');
  27.  

warto też zapoznać się z requestAnimationFrame dla animacji

Ten post edytował gitbejbe 26.04.2018, 22:28:07
Go to the top of the page
+Quote Post
SmokAnalog
post 27.04.2018, 06:31:06
Post #7





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Okej nieleniwy kolego z wiedzą. Szkoda tylko, że wkleiłeś gotowca i przerobiłeś bez zastanowienia, bo transition jest już wspierane przez każdą przeglądarkę i nie trzeba tych potworków wspierać.

Powiedz klientowi w postaci domu mody, że obrazki nie są aż tak zamazane. Good luck.
Go to the top of the page
+Quote Post
gitbejbe
post 27.04.2018, 08:16:02
Post #8





Grupa: Zarejestrowani
Postów: 515
Pomógł: 63
Dołączył: 27.08.2012

Ostrzeżenie: (0%)
-----


to nie wspieraj biggrin.gif zrób sobie z tym co chcesz, a najlepiej używaj dalej setTimeout i promise.all a na pewno lepiej już nie będzie. No i przepraszam że się w ogóle odezwałem, ciekawi mnie tylko jak sobie poradzisz z tą felerną animacją - podrzuć linka jak skończysz, z chęcią nauczę się czegoś nowego.
Go to the top of the page
+Quote Post
SmokAnalog
post 27.04.2018, 08:59:36
Post #9





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Nie poradzę sobie, bo jej nie robię. Pytanie jest tylko czysto teoretyczne o zastosowanie Promise.all. Moim zdaniem w przesuwanych i wygaszanych galeriach blokowanie interakcji z powodu niegotowych zasobów to naprawdę zły pomysł. Z kolei to ładowanie kolejnego w kolejce, nawet gdyby się na to zdecydować, to i tak nie rozwiązuje problemu możliwości zobaczenia niegotowego obrazka. Zadałem pytanie z czystej ciekawości, bo interesuje mnie taki przypadek, gdy obrazki mogą się dla kogoś ładować dobre kilka sekund, a efekt animacji trwa na przykład sekundę (pół sekundy wygaszanie, pół sekundy pojawianie). Blokowanie jakiejkolwiek interakcji to dla mnie ostateczna ostateczność. Co jeśli strona ma sporo treści i ta galeria jest na górze? Zniecierpliwiony użytkownik może po prostu ją pominąć i nawet nie zobaczy, że tam coś jeszcze jest. Można dawać oczywiście miniatury, ale nie o projektowaniu galerii jest ten temat. tongue.gif
Go to the top of the page
+Quote Post
gitbejbe
post 27.04.2018, 18:09:09
Post #10





Grupa: Zarejestrowani
Postów: 515
Pomógł: 63
Dołączył: 27.08.2012

Ostrzeżenie: (0%)
-----


Tak jak pisałem, promise to tylko handler, ten przykład który podałeś w pierwszym poście można napisac na dziesiątki róznych sposobów a i tak nie bedzie to dobrze działać - bo samo założenie jest złe. Bo co ten promise robi ? dopiero po jakimś triggerze czeka aż animacja chowania się wykona oraz obrazek zostanie załadowany, dopiero po tym wszystkim pokazuje następny obrazek. Jeśli obrazek ładuje sie dłużej niż trwa animacja, to efekt będzie taki, że na ekranie będzie widać pustkę - którą można wypełnić ewentualnie loaderem. To też jest rozwiązanie, ale nie spełnia założeń tematu. Jeśli obrazki ładowane są dynamicznie, to przecież musisz jakoś je wczytać a na pewno nie ma co oczekiwać że uda ci się je ładować w ciągu 0,5 sekundy tak aby animacja wyszła płynnie. Jedynym rozwiązaniem jest tylko jak najwcześniejsze ładowanie następnego obrazka, np właśnie poprzez ładowanie w tle od razu po wyświetleniu obecnego. Mimo to i tak nie daje to gwarancji że nie trzeba będzie czekać bo np ktoś szybko zmienia zdjęcia, ale nie wątpliwie będzie działać to o wiele lepiej.
Go to the top of the page
+Quote Post
SmokAnalog
post 28.04.2018, 00:24:43
Post #11





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Nie jestem pewien czy rozumiesz jak działa Promise.all:

[JAVASCRIPT] pobierz, plaintext
  1. Promise.all([
  2. new Promise(resolve => {setTimeout(resolve, 1000);}),
  3. new Promise(resolve => {setTimeout(resolve, 3000);})
  4. ]).then(() => {console.log('Wykonam się po trzech sekundach!');});
  5.  
  6. Promise.all([
  7. new Promise(resolve => {setTimeout(resolve, 3000);}),
  8. new Promise(resolve => {setTimeout(resolve, 1000);})
  9. ]).then(() => {console.log('Ja też się wykonam po trzech sekundach!');});
[JAVASCRIPT] pobierz, plaintext


Promise.all czeka aż wykonają się wszystkie Promise podane w tablicy, a nie kolejkuje ich w żaden sposób. Oczywiście jeśli wszystkie Promise już się wcześniej wykonały, to Promise.all...then wykonuje akcję od razu.

W przypadku wygaszania moim zdaniem bezpiecznie założyć, że obrazek nie będzie się ładował dłużej niż efekt animacji, ale jednocześnie przygotować kod na taką ewentualność. Mamy widocznie odmienne odczucia w sprawie takiej interakcji, bo dla mnie chwila czekania na treść jest mniej upierdliwa niż ograniczanie mojego klikania. Gdybym zobaczył nieaktywny przycisk przewijania pomyślałbym, że tam dalej nic nie ma i przejechałbym dalej.

Ten post edytował SmokAnalog 28.04.2018, 00:34:49
Go to the top of the page
+Quote Post
gitbejbe
post 28.04.2018, 19:45:39
Post #12





Grupa: Zarejestrowani
Postów: 515
Pomógł: 63
Dołączył: 27.08.2012

Ostrzeżenie: (0%)
-----


Wiem jak działają obietnice, nie napisałem że każda z obietnic na siebie czeka. Problem polega na tym że te promise w tym wydaniu są totalnie bez sensu. Zrozum, że skoro obietnice rozwiązujesz po z góry okresowym czasie - mimo iż nie wiesz ile czasu będziesz potrzebować, tworzy tą obietnice totalnie zbędna - bo co ona Ci obiecuje ? że setTimeout się wykona? . Dobra, zobrazuje to:

  1. setTimeout(function(){
  2. console.log('Wykonam się po trzech sekundach!');
  3. }, 3000);


Właśnie osiągnąłem ten sam efekt co Ty, zadaj sobie teraz pytanie po co w tym wszystkim promise.

dlaczego tak się uparłeś z tym setTimeout ? Nie możesz zwyczajnie przechwycić momentu wczytania obrazka i zakończenia animacji ? Teraz zakładasz że wszystko będzie trwało np te 3 sekundy. Idąc Twoim tokiem rozumowania, mogę teraz Tobie zarzucić, że zmuszasz użytkownika do irytującego czekania, skoro obrazek ładuje się 0,5 sekundy a Ty każesz i tak czekać 3 sekundy. Po za tym co gdy obrazek waży swoje a łącze nie wydala, i ładuje się np 10 sekund ? Twój skrypt po 3 sekundach i tak się wykona, mimo iż obrazka nie ma, a użytkownik stwierdzi że cos się popierniczyło i przeładuje strone. Po za tym samo założenie że coś wykona się na pewno w określonym czasie jest u podstaw złe i nie do przyjęcia. Jakbyś pracował w zespole, nikt by Tobie tego kodu nie przepuścił.

Powinieneś bardziej iść w tym kierunku:
  1.  
  2. // klikam w przycisk który ma pokazać następny obrazek
  3. $('.nextImageBtn').on('click', function(){
  4.  
  5. var $newImg;
  6.  
  7. // pierwsza obietnica -> animacja chowania pierwszego obrazka musi być zakończona
  8. var p1 = new Promise((resolve, reject) => {
  9. $gallery.one('transitionend', function(event){
  10. $gallery.removeClass('fadeOut');
  11. resolve();
  12. });
  13. $gallery.addClass('fadeOut');
  14. });
  15.  
  16.  
  17. // druga obietnica -> nowy obrazek musi być załadowany
  18. var p2 = new Promise((resolve, reject) => {
  19. var img = $("<img />").attr('src', 'obrazek.jpg').on('load', function() {
  20. $newImg = img;
  21. resolve();
  22. }
  23. });
  24.  
  25. // po spełnieniu obietnic
  26. Promise.all([p1, p2]).then(() => {
  27.  
  28. // zastąp stary obrazek
  29. $('#galery-img-container').html($newImg);
  30.  
  31. // callback dla zakończenia całego procesu
  32. $gallery.one('transitionend', function(event){
  33. $gallery.removeClass('fadeIn');
  34. });
  35.  
  36. // wywołaj animacje pojawiania się
  37. $gallery.addClass('fadeIn');
  38. });
  39.  
  40. // no i masz prostą implementacje, obietnice w końcu mają sens. Skrypt zawsze pokaże następny obrazek z animacją. Pojawienie się nowego obrazka nie wykona się szybciej niż animacja chowania a następny obrazek wraz z animacją pojawi się dopiero gdy zostanie wczytany - jeśli wczytał się krócej niż animacja chowania to animacja całego przejścia będzie płynna.
  41.  
  42. });


to tylko przykład napisany w sposób którego bardzo nie lubie - od reki na pałe, w każdym razie chodzi o zamysł a nie o to czy to działa. Mimo wszystko i tak napisałbym to zupełnie inaczej

Ten post edytował gitbejbe 28.04.2018, 20:35:02
Go to the top of the page
+Quote Post
SmokAnalog
post 28.04.2018, 20:34:51
Post #13





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Co jest bezsensownego w tym Promise.all? Masz tutaj dwie, a nie jedną asynchroniczną akcję. Jedna to ładowanie obrazka, druga to animacja. Obrazek pokazujemy tak szybko jak tylko się da, ale nie szybciej niż w momencie ukończenia animacji.

Jeżeli faktycznie można wyłapać koniec animacji w ładniejszy sposób, no to fajnie. setTimeout odpada. Podałem teraz tylko dla przykładu. Tylko że w jaki sposób sprawdzisz czy obrazek jest gotowy i animacja jest gotowa jednocześnie? Te oba kryteria muszą zajść, żeby wykonać odpowiednią akcję (pokazać obrazek). Moim zdaniem Promise.all to o wiele bardziej eleganckie rozwiązanie tu niż jakieś wzajemne sprawdzanie kryteriów na krzyż, gdzie callback animacji sprawdzi gotowość obrazka, a callback obrazka sprawdzi gotowość animacji i oba będą miały tę samą akcję w kodzie.

Twierdzę jednak, że nawet gdyby jedna z tych asynchronicznych akcji miała mieć stały czas, to nadal Promise.all jest dobrym, eleganckim rozwiązaniem.

Co tu jest, jak to mówisz, "totalnie bez sensu"?

Ten post edytował SmokAnalog 28.04.2018, 20:39:04
Go to the top of the page
+Quote Post
gitbejbe
post 28.04.2018, 23:21:23
Post #14





Grupa: Zarejestrowani
Postów: 515
Pomógł: 63
Dołączył: 27.08.2012

Ostrzeżenie: (0%)
-----


Poddaje się, poświęciłem i tak za dużo czasu. Co mi z tego że zaraz znowu się będę powtarzał, skoro i tak będziesz moje słowa przeinaczał po swojemu. Nie, nie napisałem że promise samo w sobie jest bez sensu. Sprostuje: Uważam że promise jest zajebiste, wielokrotnie korzystałem i będę korzystał podobnie jak z innych dobrodziejstw za pomocą których da się coś zrobić łatwiej, szybciej, dobrze i krócej. Uważam że jak najbardziej do takiej animacji zmiany obrazków, można byoby stworzyć bardzo klarowny kod za pomocą obietnic. Uważam że żaden kod który logicznie jest źle napisany, nie staje się automatycznie klarowny, bo został objęty w klamrę jakiejś funkcji. Zrozum, że konkretnie w tym przypadku, druga obietnica nigdy nie zostanie spełniona przed pierwszą, to jakie niby korzyści czerpiesz z tych obietnic ? Do czego mają służyć ? Jeszcze raz:

  1. // twój kod
  2. Promise.all([
  3. new Promise(resolve => {setTimeout(resolve, 1000);}),
  4. new Promise(resolve => {setTimeout(resolve, 3000);}),
  5. ]).then(() => {document.write(' KONIEC! ');});
  6.  
  7. // mój kod
  8. setTimeout(function(){ document.write(' KONIEC! '); }, 3000);


https://jsfiddle.net/mocw9oh5/7/

który kod jest klarowniejszy ? Oba działają identycznie.

Cytat
Jeżeli faktycznie można wyłapać koniec animacji w ładniejszy sposób, no to fajnie. setTimeout odpada.

Przecież podałem Tobie już 2 przykłady w kodzie jak to robić - od dawien dawna animacje przechwytuje się za pomocą zdarzeń. Stosowanie setTimeout na czas animacji to po pierwsze totalna wiocha i amatorszczyzna (serio), po drugie nigdy ale to NIGDY nie powinno się tego robić w taki sposób.

Cytat
Tylko że w jaki sposób sprawdzisz czy obrazek jest gotowy i animacja jest gotowa jednocześnie? Te oba kryteria muszą zajść, żeby wykonać odpowiednią akcję (pokazać obrazek). Moim zdaniem Promise.all to o wiele bardziej eleganckie rozwiązanie tu niż jakieś wzajemne sprawdzanie kryteriów na krzyż, gdzie callback animacji sprawdzi gotowość obrazka, a callback obrazka sprawdzi gotowość animacji i oba będą miały tę samą akcję w kodzie.


No i słusze uważasz że promise w takiej sytuacji będzie bardziej - jak to ujmujesz, eleganckie (prawidłowy przykład przedstawiłem w poprzednim poście). Nie oznacza to jednak że samo zastosowanie promise będzie miało sens, skoro zrobisz to źle, bo robisz to źle myślac własnie w ten sposób:

Cytat
Twierdzę jednak, że nawet gdyby jedna z tych asynchronicznych akcji miała mieć stały czas, to nadal Promise.all jest dobrym, eleganckim rozwiązaniem.


Nie ma w tym konkretnie przykładzie kilku asynchronicznych akcji. Jest tylko jedna - ładowanie obrazka, której ty i tak nie wykonujesz bo zamykasz to w timeoutcie. Druga akcja to animacja, której zakończenie określasz też w timeout'cie, który to trwa zawsze krócej niz wczytywanie obrazka. Co Ci z tego przywileju promise.all, który zrzuca z ciebie całe te jarzmo sprawdzania wzajemnie callbacków, skoro i tak nawet z tego nie korzystasz - bo pierwszą obietnice ZAWSZE spełniasz po sekundzie, a drugą ZAWSZE po 3 sekundach, więc finalnie nie musisz nawet sprawdzać czy pierwsza się wykona, skoro druga ZAWSZE będzie wykonywać się po pierwszej i będzie jednocześnie ostatnią, rozumiesz ? To jest totalnie bez sensu. Cały ten Twój kod mógłbym napisać w ten sposób i działałby identycznie:
  1. //rozpocznij animacje która trwa sekundę
  2. $('#gallery').addClass('fadeOut');
  3.  
  4. // załaduj obrazek do zmiennej
  5. var img = $("<img />").attr('src', 'obrazek.jpg')
  6.  
  7. // po 3 sekundach wstaw obrazek, bez względu na to czy się załadował
  8. setTimeOut(function(){
  9. $('#gallery-img-container').html(img);
  10. }, 3000);


Poświęciłem wystarczająco dużo czasu, wróć do poprzednich postów, przeczytaj je jeszcze raz i przeanalizuj. Podałem Tobie rozwiązania w teorii a nawet w kodzie. Na dalszą dyskusje nie mam już siły a nawet chęci.
Go to the top of the page
+Quote Post
SmokAnalog
post 29.04.2018, 08:02:45
Post #15





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Przecież to z dwoma setTimeout to był tylko przykład jak działa Promise.all., odwróciłeś kota ogonem i uznałeś, że uważam ten kod za jakiś z życia wzięty.

Cytat(gitbejbe @ 29.04.2018, 00:21:23 ) *
Nie ma w tym konkretnie przykładzie kilku asynchronicznych akcji. Jest tylko jedna - ładowanie obrazka, której ty i tak nie wykonujesz bo zamykasz to w timeoutcie. Druga akcja to animacja, której zakończenie określasz też w timeout'cie, który to trwa zawsze krócej niz wczytywanie obrazka. Co Ci z tego przywileju promise.all, który zrzuca z ciebie całe te jarzmo sprawdzania wzajemnie callbacków, skoro i tak nawet z tego nie korzystasz - bo pierwszą obietnice ZAWSZE spełniasz po sekundzie, a drugą ZAWSZE po 3 sekundach


I tu mamy chyba odpowiedź czego nie rozumiesz. Dlaczego uznajesz, że wczytywanie obrazka zawsze będzie krótsze niż animacja? Przecież to bzdura. Być może nie rozumiesz sekwencji w tej animacji, która wygląda następująco:

  1. Rozpoczęcie animacji wygaszania nieaktualnego już obrazka i jednoczesne rozpoczęcie ładowania nowego
  2. Pojawienie się nowego obrazka, ale dopiero gdy ten następny już jest gotowy


Tak naprawdę to jeśli wygaszanie trwa pół sekundy i pojawianie się również, to:

Jeżeli obrazek wczytuje się krócej niż pół sekundy, musi poczekać na zakończenie animacji i opóźnienie między jedną animacją a drugą wynosi 0s
Jeżeli obrazek wczytuje się dłużej niż pół sekundy, to animacja pojawiania się czeka na obrazek i opóźnienie między jedną animacją a drugą wynosi [czas ładowania obrazka] minus 0.5s, bo w momencie zakończenia znikania, obrazek jest już 0.5s w trakcie ładowania się.

Nieprzyjemnie piszesz jak do jakiegoś kretyna, podczas gdy to Ty nie rozumiesz pytania, ale z grzeczności nie będę pisał o czym to świadczy. Jak masz się wymądrzać i udawać zmęczonego życiem eksperta, to nic już tu nie pisz.
Go to the top of the page
+Quote Post
gitbejbe
post 29.04.2018, 08:47:53
Post #16





Grupa: Zarejestrowani
Postów: 515
Pomógł: 63
Dołączył: 27.08.2012

Ostrzeżenie: (0%)
-----


napisałem Tobie kod - post z wczoraj 20:45, robi wszystko tak jak napisałeś, bez zadnych timeotów, wszystko na siebie czeka i wykonuje się w odpowiedniej sekwencji. Dalej rozmowa z dupy. 3maj sie
Go to the top of the page
+Quote Post
SmokAnalog
post 29.04.2018, 09:03:43
Post #17





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Dzięki. Niepotrzebnie napisałeś kod, bo temat jest teoretyczny i naprawdę wiem jak to zrobić, ale doceniam nakład pracy. Chodziło mi tylko o odpowiedź czy Promise.all to dobry pomysł w podobnych sytuacjach i miło, że się ze mną zgadzasz, że tak.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 9.05.2024 - 09:37