🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.javascript
8 messages
8 total messages Started by Roman Tyczka Tue, 07 Aug 2018 16:35
Promise i oczekiwanie na wynik
#50407
Author: Roman Tyczka
Date: Tue, 07 Aug 2018 16:35
23 lines
739 bytes
Witam,

Moje boje z JS utknęły na tym, że liczenie haszy w bibliotece standardowej
jest asynchroniczne i całość rozbija się o obiekt typu Promise zwracany z
metody digest().
Czytam o tym nieszczęsnym Promise i nie ogarniam.
Chciałbym poczekać aż w tle zostanie policzony czas, więc na końcu funkcji
haszującej dopisuję:


 Promise.race([hash_promise]).then(function (value) {
			haszyk = value;
		});
 return haszyk;

spodziewając się, że race() będzie czekać, tymczasem race() przechodzi bez
zatrzymania, mimo, że hash_promise nadal jest pending i do return trafia
pusty string haszyk, bo go nikt nie wypełnił.

Jak zmusić JS, żeby czekał aż asynchroniczne zadanie będzie wykonane?

--
pozdrawiam
Roman Tyczka
Re: Promise i oczekiwanie na wynik
#50409
Author: Borys =?utf-8?Q?
Date: Wed, 08 Aug 2018 22:29
23 lines
982 bytes
Dnia Tue, 7 Aug 2018 16:35:54 +0200, Roman Tyczka napisał(a):

> spodziewając się, że race() będzie czekać, tymczasem race() przechodzi bez
> zatrzymania, mimo, że hash_promise nadal jest pending i do return trafia
> pusty string haszyk, bo go nikt nie wypełnił.

Nie wkleiłeś całego kodu, ale czy przypadkiem nie zwracasz zmiennej
"haszyk" od razu? Ona zostanie zmieniona dopiero gdy Promise się rozwiąże.

I generalnie Promise.race() nie do tego służy. To stosunkowo rzadko
potrzebne narzędzie, które czeka na wynik jednej z wielu promises. Niby
można by tego użyć w zaproponowany przez Ciebie sposób, ale jest to
kompletnie zbędne. Wystarczy się od razu odwołać do obiektu.

> Jak zmusić JS, żeby czekał aż asynchroniczne zadanie będzie wykonane?

Nie zmusisz. Musisz myśleć asynchronicznie - kod operujący na wyniku
funkcji haszującej musi poczekać na wynik Promise:

https://jsfiddle.net/fzLbqmng/

--
Borys Pogoreło
borys(#)leszno,edu,pl
Re: Promise i oczekiwanie na wynik
#50411
Author: Roman Tyczka
Date: Wed, 08 Aug 2018 23:34
51 lines
2223 bytes
On Wed, 8 Aug 2018 22:29:26 +0200, Borys Pogoreło wrote:

> Dnia Tue, 7 Aug 2018 16:35:54 +0200, Roman Tyczka napisał(a):
>
>> spodziewając się, że race() będzie czekać, tymczasem race() przechodzi bez
>> zatrzymania, mimo, że hash_promise nadal jest pending i do return trafia
>> pusty string haszyk, bo go nikt nie wypełnił.
>
> Nie wkleiłeś całego kodu, ale czy przypadkiem nie zwracasz zmiennej
> "haszyk" od razu? Ona zostanie zmieniona dopiero gdy Promise się rozwiąże.
>
> I generalnie Promise.race() nie do tego służy. To stosunkowo rzadko
> potrzebne narzędzie, które czeka na wynik jednej z wielu promises. Niby
> można by tego użyć w zaproponowany przez Ciebie sposób, ale jest to
> kompletnie zbędne. Wystarczy się od razu odwołać do obiektu.
>
>> Jak zmusić JS, żeby czekał aż asynchroniczne zadanie będzie wykonane?
>
> Nie zmusisz. Musisz myśleć asynchronicznie - kod operujący na wyniku
> funkcji haszującej musi poczekać na wynik Promise:
>
> https://jsfiddle.net/fzLbqmng/

Powiedzmy, że rozumiem jako tako jak to działa, jest to dość sprytne.
Tylko, że teraz jest problem. Mam kod, który wywołuję pod buttonem, to
klasyczny kod sekwencyjny. Linia po linii zbiera dane, łączy stringi, liczy
hasze, coś tam jeszcze robi i na końcu wrzuca wynik do jakiegoś
pola/zmiennej. I jeśli teraz jedna potrzebna funkcja czyli hasz narzuca mi
styl asynchroniczny to zmusza do przeorania całego kodu na ten model i
wołania wszystkiego w kolejnych promisach i then'ach. Pewnie, że to fajne,
elastyczne i generalnie lepsze, ale są sytuacje gdy nie chcę przerabiać
kodu do tej wymuszonej asynchroniczności, co wtedy?

Przykładowo mam stary kod:

 value = valueX + valuY + SHA512(valueZ);
 value = cryptoAES(value);

Prosta rzecz. A teraz muszę ten cały kod zawijać w, skądinnąd użyteczne,
ale wygibasy, promisów.

Czy mogę jakoś wymusić synchroniczność? Próbowałem z tym async/await ale to
nie zadziałało. Może coś źle robiłem, a może to musi być nowsza
przeglądarka.


ps. dlaczego w ogóle ten moduł crypto wsadzili w Promise? Z powodu
złożoności obliczeniowej i realnie długiego czasu wykonania?

--
pozdrawiam
Roman Tyczka
Re: Promise i oczekiwanie na wynik
#50414
Author: Borys =?utf-8?Q?
Date: Fri, 10 Aug 2018 11:53
26 lines
1042 bytes
Dnia Wed, 8 Aug 2018 23:34:09 +0200, Roman Tyczka napisał(a):

> I jeśli teraz jedna potrzebna funkcja czyli hasz narzuca mi
> styl asynchroniczny to zmusza do przeorania całego kodu na ten model i
> wołania wszystkiego w kolejnych promisach i then'ach. Pewnie, że to fajne,
> elastyczne i generalnie lepsze, ale są sytuacje gdy nie chcę przerabiać
> kodu do tej wymuszonej asynchroniczności, co wtedy?

Wtedy masz problem ;)

Niestety kod asynchroniczny wymaga innej budowy i uwzględnienia tego, że
trzeba czekać na wynik. Nawet tylko jeden cykl CPU, ale trzeba.

> Czy mogę jakoś wymusić synchroniczność? Próbowałem z tym async/await ale to
> nie zadziałało. Może coś źle robiłem, a może to musi być nowsza
> przeglądarka.

To i to. W drugim wątku wrzuciłem przykład.

> ps. dlaczego w ogóle ten moduł crypto wsadzili w Promise? Z powodu
> złożoności obliczeniowej i realnie długiego czasu wykonania?

Tak. Wszelkie operacje synchroniczne blokują event loop.

--
Borys Pogoreło
borys(#)leszno,edu,pl
Re: Promise i oczekiwanie na wynik
#50417
Author: Roman Tyczka
Date: Fri, 10 Aug 2018 12:49
25 lines
947 bytes
On Fri, 10 Aug 2018 11:53:03 +0200, Borys Pogoreło wrote:

>> I jeśli teraz jedna potrzebna funkcja czyli hasz narzuca mi
>> styl asynchroniczny to zmusza do przeorania całego kodu na ten model i
>> wołania wszystkiego w kolejnych promisach i then'ach. Pewnie, że to fajne,
>> elastyczne i generalnie lepsze, ale są sytuacje gdy nie chcę przerabiać
>> kodu do tej wymuszonej asynchroniczności, co wtedy?
>
> Wtedy masz problem ;)
>
> Niestety kod asynchroniczny wymaga innej budowy i uwzględnienia tego, że
> trzeba czekać na wynik. Nawet tylko jeden cykl CPU, ale trzeba.

[...]

>> ps. dlaczego w ogóle ten moduł crypto wsadzili w Promise? Z powodu
>> złożoności obliczeniowej i realnie długiego czasu wykonania?
>
> Tak. Wszelkie operacje synchroniczne blokują event loop.

Powiedz mi jak to w ogóle działa pod spodem, skoro JS jest niby
jednowątkowy? Jak przerwania w epoce DOSa na PC AT?

--
pozdrawiam
Roman Tyczka
Re: Promise i oczekiwanie na wynik
#50418
Author: Cezary Tomczyk
Date: Fri, 10 Aug 2018 17:22
13 lines
483 bytes
On 10/08/2018 12:53, Borys Pogoreło wrote:
> Dnia Wed, 8 Aug 2018 23:34:09 +0200, Roman Tyczka napisał(a):
[...]
>> ps. dlaczego w ogóle ten moduł crypto wsadzili w Promise? Z powodu
>> złożoności obliczeniowej i realnie długiego czasu wykonania?
>
> Tak. Wszelkie operacje synchroniczne blokują event loop.

Garść o tym:
https://medium.com/@siddharthac6/javascript-execution-of-synchronous-and-asynchronous-codes-40f3a199e687

--
Cezary Tomczyk
http://www.ctomczyk.pl/
Re: Promise i oczekiwanie na wynik
#50419
Author: Roman Tyczka
Date: Fri, 10 Aug 2018 18:19
46 lines
2185 bytes
On Fri, 10 Aug 2018 17:22:02 +0300, Cezary Tomczyk wrote:

> On 10/08/2018 12:53, Borys Pogoreło wrote:
>> Dnia Wed, 8 Aug 2018 23:34:09 +0200, Roman Tyczka napisał(a):
> [...]
>>> ps. dlaczego w ogóle ten moduł crypto wsadzili w Promise? Z powodu
>>> złożoności obliczeniowej i realnie długiego czasu wykonania?
>>
>> Tak. Wszelkie operacje synchroniczne blokują event loop.
>
> Garść o tym:
> https://medium.com/@siddharthac6/javascript-execution-of-synchronous-and-asynchronous-codes-40f3a199e687

To nie wyjaśnia wszystkiego, bo użyty został fatalny przykład z tym
setTimeout(). Czekanie 2 sekundy nic nie kosztuje. I jest łatwe do
implementacji tak jak to opisano.
Ale co z sytuacją, gdy funkcja asynchroniczna robi coś "grubego" w tle, jak
choćby to liczenie hasza?
Czy wtedy:
a) jest oczekiwanie na pustego call stacka i wrzucenie całego "grubego"
zadania do wykonania (tak wynika z artykułu)?
b) czy może to poboczne zadanie jest dzielone na fragmenciki i wywoływane
po kawałku w wolnych chwilach (tak jak w aplikacjach z prawdziwą
wielowątkowościa)?

Druga opcja ma większy sens, ale jest dużo trudniejsza w implementacji.
Zatem nadal nie wiem czy wiem co się tam tak naprawdę dzieje :-)

Zwłaszcza, że autor arta sam pisze na końcu:

"I don’t know how accurately I am able to demonstrate this topic but there
are a lot in between that could have been elaborated or explained better,
but am in a rush and it’s already too long already. Hope it helps someone."

ps. W Delphi (jeśli mowa o programowaniu bez wątków) też istnieje coś
takiego jak timer i też można mu zapodać zrobienie czegoś za określony czas
i działa to tak jak opisano w tym artykule, czyli pętla komunikatów dostaje
komunikat WM_TIMER i adres procedury obsługi, którą wywołuje jeśli nie jest
akurat niczym zajęta. To dość uboga "asynchroniczność", ale czasami
wystarcza. Gdyby jednak procedura spod timera była długotrwała to pętla
komunikatów zostanie zablokowana i aplikacja przestanie odpowiadać (często
to widać w źle napisanych aplikacjach, gdy GUI przestaje się rysować i nie
działają kontrolki).

--
pozdrawiam
Roman Tyczka
Re: Promise i oczekiwanie na wynik
#50421
Author: Borys =?utf-8?Q?
Date: Fri, 10 Aug 2018 22:31
20 lines
815 bytes
Dnia Fri, 10 Aug 2018 18:19:58 +0200, Roman Tyczka napisał(a):

> Ale co z sytuacją, gdy funkcja asynchroniczna robi coś "grubego" w tle, jak
> choćby to liczenie hasza?
> Czy wtedy:
> a) jest oczekiwanie na pustego call stacka i wrzucenie całego "grubego"
> zadania do wykonania (tak wynika z artykułu)?

Całe zadanie. Jednowątkowość do bólu (pominąwszy webworkery). Dlatego warto
jak najbardziej kroić skomplikowany kod.

> wystarcza. Gdyby jednak procedura spod timera była długotrwała to pętla
> komunikatów zostanie zablokowana i aplikacja przestanie odpowiadać (często
> to widać w źle napisanych aplikacjach, gdy GUI przestaje się rysować i nie
> działają kontrolki).

Javascriptem też zablokujesz UI, jeśli odpalisz coś "ciężkiego".

--
Borys Pogoreło
borys(#)leszno,edu,pl
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