K čemu JavaScript generátory?

Vertex

K čemu JavaScript generátory?
« kdy: 12. 08. 2015, 16:41:55 »
Zdravim,

vie mi niekto polopate  vysvetlit na čo sú dobré generátory v JS? Prečítal som niekoľko článkov a stále mi vôbec nie je jasné čo to má ako byť.
Argumentuje sa, že to zabráni callback hell, ale mne to príde, že namiesto callback hell tam teraz bude generator hell. Okrem toho pri použíti
generátorov mi vôbec nie je jasné ako aplikácia prebieha, kedy sa čo vykoná, pri callbackoch sa mi o tom uvažuje oveľa jednoduchšie.

Ďakujem.
« Poslední změna: 12. 08. 2015, 21:23:09 od Petr Krčmář »


Radek Miček

Re:JavaScript generatory
« Odpověď #1 kdy: 12. 08. 2015, 17:37:24 »
na čo sú dobré generátory v JS?

V podstatě se můžete dostat k vymezené kontinuaci (angl. delimited continuation), která jde použít nejvýše jednou a nemůže předat hodnotu zpět do funkce (next nebere žádný argument). Když píšete callbacky, musíte udělat podobnou transformaci ručně - u generátorů to udělá prohlížeč za vás.

Yield si můžete představit jako throw (tj. příkaz vyhazující výjimku), s tím rozdílem, že se později po vyhození a odchycení výjimky můžete vrátit za místo, kde byla výjimka vyhozena (za příkaz throw), a pokračovat v běhu. Mj. napsal jsem článek Algebraické efekty - netýká se však pouze generátorů (generátory jsou pouze speciálním případem algebraických efektů).

Citace
Okrem toho pri použíti generátorov mi vôbec nie je jasné ako aplikácia prebieha, kedy sa čo vykoná

IMO dá se na to zvyknout.

Radek Miček

Re:JavaScript generatory
« Odpověď #2 kdy: 12. 08. 2015, 17:45:41 »
Citace
jednou a nemůže předat hodnotu zpět do funkce (next nebere žádný argument)

To se mělo týkat pouze iterátorů, jinak samozřejmě next bere argument, jinak by asynchronní volání nemohly nic vracet.

JS

Re:K čemu JavaScript generátory?
« Odpověď #3 kdy: 13. 08. 2015, 06:24:09 »
Generatory v JS neznam, takze to ber s rezervou, na zaklade moji zkusenosti s Pythonem, ktery ma generatory.

Myslim, ze hlavni vyhodou je, ze nemusis umele delit kod do dvou funkci (treba asynchronni volani a callback), ale muzes je dat do jednoho bloku. To zprehlednuje kod, protoze nemusis preskakovat pri cteni do te druhe funkce. Je to tedy v podstate vyjadrenim myslenky, ze sekvencni kod, ktery spolu souvisi, by mel byt definovany v ramci jedne funkce nebo procedury.

k

Re:JavaScript generatory
« Odpověď #4 kdy: 13. 08. 2015, 08:42:23 »
vie mi niekto polopate  vysvetlit na čo sú dobré generátory v JS?

Generátor ušetří neustálé předávání callbacku do funkce, automaticky se uvažuje že callback je na kód následující za NEXT a tento automatický callback se používá YIELD.
Mimo to má callback vlastní stack i lokální proměné existující po celou dobu existence generátoru, takže se s tím dají dělat zajímavé věci, trochu to připomíná kooperativní vlákna. Kód generátoru se tak dá pozastavit tím YIELD a pak se vrátit a pokračovat.

asynchronni volani
asynchronní volání

V JS nic takového jako asynchronní volání neexistuje, všechno co je zapsáno v javascriptu je bezvýhradně synchronní.


Radek Miček

Re:JavaScript generatory
« Odpověď #5 kdy: 13. 08. 2015, 09:14:26 »
V JS nic takového jako asynchronní volání neexistuje, všechno co je zapsáno v javascriptu je bezvýhradně synchronní.

Co tedy určuje třetí parametr async u XMLHttpRequest.open?

Rovněž handlery událostí jsou spouštěny asynchroně.

k

Re:JavaScript generatory
« Odpověď #6 kdy: 13. 08. 2015, 09:40:08 »
async znamená že kód mimo JS, obvykle v C/C++, skutečně běží asynchronně.
Handlery událostí jsou ovšem spouštěny synchronně s ostatními funkcemi, například handler od timeru není spuštěn tehdy kdy má, ale až se ostatní funkce milostivě uráčí skončit, to je v rozporu s asynchronicitou.

Radek Miček

Re:JavaScript generatory
« Odpověď #7 kdy: 13. 08. 2015, 10:22:36 »
async znamená že kód mimo JS, obvykle v C/C++, skutečně běží asynchronně.

Podstatné je, že po dobu provádění požadavku může aplikace provádět jinou činnost a nezatuhne. Kdyby to bylo synchronní, tak by aplikace (přesněji volající vlákno - jenže v JS máte obvykle jedno vlákno) zatuhla (např. by nezpracovávala žádné událost), dokud by požadavek neskončil. Je irelevantní, jak je to implementováno.

Citace
Handlery událostí jsou ovšem spouštěny synchronně s ostatními funkcemi, například handler od timeru není spuštěn tehdy kdy má, ale až se ostatní funkce milostivě uráčí skončit, to je v rozporu s asynchronicitou.

Mám na mysli skutečnost, že vyhození události např. pomocí setInterval(f, 0) nezpůsobí zablokování volajícího kódu, dokud událost není zpracována (dokud f nedoběhne).

k

Re:JavaScript generatory
« Odpověď #8 kdy: 13. 08. 2015, 11:03:49 »
Antonymum synchronní není neblokující. setInterval(f, 0) je neblokující, ale ne asynchronní, kdyby býval byl setInterval(f, 0) asynchronní, potom by k zahájení vykonávání f došlo bezprostředně a v jeden čas by tak běžely dvě funkce najednou a to v JS není možné.

v

Re:JavaScript generatory
« Odpověď #9 kdy: 13. 08. 2015, 11:26:00 »
Antonymum synchronní není neblokující. setInterval(f, 0) je neblokující, ale ne asynchronní, kdyby býval byl setInterval(f, 0) asynchronní, potom by k zahájení vykonávání f došlo bezprostředně a v jeden čas by tak běžely dvě funkce najednou a to v JS není možné.

tedy asynchronnost lze realizovat pouze na víceprocesorovém (vícejádrovém) systému?

Ivoszz

Re:K čemu JavaScript generátory?
« Odpověď #10 kdy: 13. 08. 2015, 13:17:10 »
Nejsem velkým znalcem (ani příznivcem) akademické terminologie, ale pokud aspoň lehce kouknu do wikipedie na heslo asynchronní, které není v rozporu jak asynchronnost za ta léta chápu já, nevidím tam jedinou zmínku o současném (paralelním) vykonávaní. Naopak, naprosto v souladu s chápáním synchronních (taktovaných) a asynchronních elektrických obvodů se bavíme o tom, kdy může přijít požadavek. Zda bude zpracován pomocí preemptivního (přerušení, priority) nebo kooperativního multitaskingu (eventloop - až bude volno) je jen implementační detail.

k

Re:JavaScript generatory
« Odpověď #11 kdy: 13. 08. 2015, 13:33:28 »
tedy asynchronnost lze realizovat pouze na víceprocesorovém (vícejádrovém) systému?

Všude tam kde mají preemptivní multithreading, ve smyslu jak je to známo třeba z C#.

Naopak, naprosto v souladu s chápáním synchronních (taktovaných) a asynchronních elektrických obvodů se bavíme o tom, kdy může přijít požadavek. Zda bude zpracován pomocí preemptivního (přerušení, priority) nebo kooperativního multitaskingu (eventloop - až bude volno) je jen implementační detail.

To právě není detail, příjem znaků z asynchronní sériové linky musíte zpracovat přiměřeně rychle, ne až nějaký hlupák dokončí pětiminutový výpočet a uvolní tak eventloop, to už budou znaky nenávratně ztraceny.

v

Re:JavaScript generatory
« Odpověď #12 kdy: 13. 08. 2015, 13:53:31 »
v jeden čas by tak běžely dvě funkce najednou

tedy asynchronnost lze realizovat pouze na víceprocesorovém (vícejádrovém) systému?
Všude tam kde mají preemptivní multithreading, ve smyslu jak je to známo třeba z C#.
ale na jednoprocesorovém systému nepoběží obě funkce naráz, jsou tedy nutné alespoň dva procesory, ano?

Radek Miček

Re:JavaScript generatory
« Odpověď #13 kdy: 13. 08. 2015, 13:59:42 »
tedy asynchronnost lze realizovat pouze na víceprocesorovém (vícejádrovém) systému?

Všude tam kde mají preemptivní multithreading, ve smyslu jak je to známo třeba z C#.

Citace
kdyby býval byl setInterval(f, 0) asynchronní, potom by k zahájení vykonávání f došlo bezprostředně a v jeden čas by tak běžely dvě funkce najednou a to v JS není možné.

Mj., momentální implementace asynchronních operací v .NET Frameworku (tj. i C#) rovněž nezaručuje, že se asynchronní operace začne vykonávat bezprostředně (např., když jsou všechna vlákna ve ThreadPoolu obsazená). A řada jiných implementací je na tom podobně.

Citace
Antonymum synchronní není neblokující.

Právě bych řekl, že ano. Jinak řečeno synchronní a blokující je totéž (alespoň já to tak chápu) - viz třeba Wikipedie: But such an approach (called synchronous I/O or blocking I/O) would block the progress of a program while the communication is in progress.

k

Re:JavaScript generatory
« Odpověď #14 kdy: 13. 08. 2015, 14:26:23 »
Vysvětlím polopaticky, máme funkci FOO pět minut počítající FFT, mezitím přijdou data ze soketu, takže se ihned vyvolá asynchronně funkce BAR a zcela nezávisle na FOO data zobrazí na monitoru. Bez asynchronnosti by se funkce BAR zavolala až po skončení FOO, přesně tak jako se to děje v JS.
Myslím že už jsem to vysvětlil dostatečně. (Uvedené chování jde zajistit i na jednoprocesorovém stroji)