Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > pl.comp.lang.javascript > #3482 > unrolled thread
| Started by | Roman Tyczka <noemail@because.no> |
|---|---|
| First post | 2018-08-07 16:35 +0200 |
| Last post | 2018-08-10 22:31 +0200 |
| Articles | 8 — 3 participants |
Back to article view | Back to pl.comp.lang.javascript
Promise i oczekiwanie na wynik Roman Tyczka <noemail@because.no> - 2018-08-07 16:35 +0200
Re: Promise i oczekiwanie na wynik Borys Pogoreło <borys@pl.edu.leszno> - 2018-08-08 22:29 +0200
Re: Promise i oczekiwanie na wynik Roman Tyczka <noemail@because.no> - 2018-08-08 23:34 +0200
Re: Promise i oczekiwanie na wynik Borys Pogoreło <borys@pl.edu.leszno> - 2018-08-10 11:53 +0200
Re: Promise i oczekiwanie na wynik Roman Tyczka <noemail@because.no> - 2018-08-10 12:49 +0200
Re: Promise i oczekiwanie na wynik Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2018-08-10 17:22 +0300
Re: Promise i oczekiwanie na wynik Roman Tyczka <noemail@because.no> - 2018-08-10 18:19 +0200
Re: Promise i oczekiwanie na wynik Borys Pogoreło <borys@pl.edu.leszno> - 2018-08-10 22:31 +0200
| From | Roman Tyczka <noemail@because.no> |
|---|---|
| Date | 2018-08-07 16:35 +0200 |
| Subject | Promise i oczekiwanie na wynik |
| Message-ID | <1jv3988qj6pyf.dlg@tyczka.com> |
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
[toc] | [next] | [standalone]
| From | Borys Pogoreło <borys@pl.edu.leszno> |
|---|---|
| Date | 2018-08-08 22:29 +0200 |
| Message-ID | <nu2wq6mg704y$.wuh3wxwx318r$.dlg@40tude.net> |
| In reply to | #3482 |
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
[toc] | [prev] | [next] | [standalone]
| From | Roman Tyczka <noemail@because.no> |
|---|---|
| Date | 2018-08-08 23:34 +0200 |
| Message-ID | <1x6oxswxeel0t$.dlg@tyczka.com> |
| In reply to | #3484 |
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
[toc] | [prev] | [next] | [standalone]
| From | Borys Pogoreło <borys@pl.edu.leszno> |
|---|---|
| Date | 2018-08-10 11:53 +0200 |
| Message-ID | <19s5kvtfto3zr.bj8wdjlcy4l2.dlg@40tude.net> |
| In reply to | #3486 |
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
[toc] | [prev] | [next] | [standalone]
| From | Roman Tyczka <noemail@because.no> |
|---|---|
| Date | 2018-08-10 12:49 +0200 |
| Message-ID | <f1k2ujtqa5x8$.dlg@tyczka.com> |
| In reply to | #3488 |
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
[toc] | [prev] | [next] | [standalone]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2018-08-10 17:22 +0300 |
| Message-ID | <pkk72b$2gvk$1@csiph.com> |
| In reply to | #3488 |
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/
[toc] | [prev] | [next] | [standalone]
| From | Roman Tyczka <noemail@because.no> |
|---|---|
| Date | 2018-08-10 18:19 +0200 |
| Message-ID | <3gdptg2lfrnd.dlg@tyczka.com> |
| In reply to | #3493 |
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
[toc] | [prev] | [next] | [standalone]
| From | Borys Pogoreło <borys@pl.edu.leszno> |
|---|---|
| Date | 2018-08-10 22:31 +0200 |
| Message-ID | <1isg2tvyhs2z2$.11w8obwnohoid$.dlg@40tude.net> |
| In reply to | #3494 |
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
[toc] | [prev] | [standalone]
Back to top | Article view | pl.comp.lang.javascript
csiph-web