Jak čekat na výsledky v Javascript

učeň

Jak čekat na výsledky v Javascript
« kdy: 20. 11. 2015, 11:52:32 »
Ahoj, začínám s Javascriptem a zjistil jsem, že volaná funkce jako by nečekala na výsledek, jen spustí funkci a jde dál. Je to chyba nebo vlastnost ? Pokud je to vlastnost, jak mám psát kód když potřebuji výsledky z těch funkcí ? Děkuji


robin martinez

  • *****
  • 1 138
  • Have you hugged your toilet today?
    • Zobrazit profil
    • Null Storage
    • E-mail
Re:Jak čekat na výsledky v Javascript
« Odpověď #1 kdy: 20. 11. 2015, 12:07:09 »
Vlastnost, JS je asynchronní - neblokovací, funkce mají většinou jako parametr nějaký callback, který se zavolá, pokud byla operace úspěšná, neúspěšná.
One machine can do the work of fifty ordinary men. No machine can do the work of one extraordinary man.

I do Linux, Hardware and spaghetti code in PHP, Python and JavaScript

k

Re:Jak čekat na výsledky v Javascript
« Odpověď #2 kdy: 20. 11. 2015, 13:06:34 »
Ahoj, začínám s Javascriptem a zjistil jsem, že volaná funkce jako by nečekala na výsledek, jen spustí funkci a jde dál. Je to chyba nebo vlastnost ? Pokud je to vlastnost, jak mám psát kód když potřebuji výsledky z těch funkcí ? Děkuji

Je to vlastnost. Funkce v JS zahájí operaci mimo jazyk JS a skončí a kód v JS pokračuje dál. Po dokončení operace mimo JS tato zavolá tvůj callback v JS. Callback se zavolá až tehdy, když JS zrovna nic nedělá.

Vlastnost, JS je asynchronní.

JS je čistě synchronní záležitost, kromě novinky Worker. Asynchronní operace jsou realizovány mimo jazyk JS.

Zdenek Henek nereg

Re:Jak čekat na výsledky v Javascript
« Odpověď #3 kdy: 20. 11. 2015, 13:48:00 »
Ahoj, začínám s Javascriptem a zjistil jsem, že volaná funkce jako by nečekala na výsledek, jen spustí funkci a jde dál. Je to chyba nebo vlastnost ? Pokud je to vlastnost, jak mám psát kód když potřebuji výsledky z těch funkcí ? Děkuji

Na clien server komunikaci a callbacky pouzivame toto:
https://api.jquery.com/promise/
https://developer.mozilla.org/cs/docs/Web/JavaScript/Reference/Global_Objects/Promise

sj

Re:Jak čekat na výsledky v Javascript
« Odpověď #4 kdy: 20. 11. 2015, 13:51:09 »
učeň: můžeš ukázat kus kódu?

Jestli funkcí myslíš normální function která dělá nějaký výpočet tak to by mělo normálně čekat (resp. je to synchronní). Co může být asynchronní je např. posílání dotazů na jiné servery.


.

Re:Jak čekat na výsledky v Javascript
« Odpověď #5 kdy: 20. 11. 2015, 14:45:00 »
Je to jednoduché, v tom výpočtu se pokračuje ve funkci, kterou předáváš jako parametr (tzv. callback). Původní funkce/modul skončí.
Podobné nástroje jsou i v jiných jazycích (lambda funkce, ...), ale nejsou tolik využívány.

Nepíšeš, jestli se ti jedná o node.js nebo web, doporučuji se podívat na nějaké tutoriály. Na internetu je toho hodně.

čumil

Re:Jak čekat na výsledky v Javascript
« Odpověď #6 kdy: 20. 11. 2015, 14:50:35 »
Někde tady zazněla kravina že kód který je asynchronní běží mimo engine JS (nativní kód). Blbost. Může se tak dít ale není to pravidlo. Asynchronní funkci si můžeš udělat i sám. Dejme tomu že máš nějaký problém který sežere hodně výkonu a nechceš aby ti to zabilo stránku (a nechceš či nemůžeš použít worker). Jak to udělat? Uděláš z té náročné operace asynchronní operaci. Jediné co budeš potřebovat je náročnou operaci rozsekat na "kroky" a tyto kroky poté vykonat postupně pomocí setTimeout (interně využívá frontu eventů, což je jádro asynchronicity), výsledek někam pošleš právě pomocí callbacku (poslední krok). Výsledkem bude reagující stránka a výsledek náročného výpočtu.

A jak se zbavit asynchronicity? V nodejs jsou na to knihovny vnitřně využívající nativních pluginů. V prohlížeči máš smůlu, async a await je v ES7, na prohlížeči si rád za ES5, takže máš na klientu smůlu.

Zopper

  • *****
  • 657
    • Zobrazit profil
Re:Jak čekat na výsledky v Javascript
« Odpověď #7 kdy: 20. 11. 2015, 15:27:58 »
[...]Uděláš z té náročné operace asynchronní operaci. Jediné co budeš potřebovat je náročnou operaci rozsekat na "kroky" a tyto kroky poté vykonat postupně pomocí setTimeout [...]
Jenže setTimeout není úplně asynchronní. Jediná skutečně asynchronní věc na něm je ten časovač. Samotné provádění je ale sekvenční - když vyprší časovač, dokonční se aktuální operace a začne se provádět funkce nastavená v setTimeout. Ta se provede, a pak se obnoví původní běh. Pokud je více setTimeout nastaveno na stejný okamžik, tak se provádí sekvenčně, vždycky až když skript opustí předchozí callback.

Takže jediné smysluplné využití setTimeout v tuhle chvíli by bylo mít opravdu hodně malých kroků (max ~desítky ms na jeden) a mezi nimi mít nějaký rozumně velký časový úsek na ostatní věci, v závislosti na tom, jestli se takových náročných operací provádí víc najednou, na obsluhu GUI... Přidejme špetku generičnosti a jsme vlastně u implementace jednoduchého scheduleru pro jednoprocesorový systém, akorát místo HW časovače máme setTimeout...

k

Re:Jak čekat na výsledky v Javascript
« Odpověď #8 kdy: 20. 11. 2015, 15:47:34 »
Uděláš z té náročné operace asynchronní operaci.

V tom se často chybuje. Hlavní smysl asynchronní funkce je právě ten, že během jejího vykonávání můžeš dělat svou jinou práci a nemusíš se o to nijak starat. Zavádělo se to právě proto, že multiplexovat to ručně tvým způsobem byla otrocká práce s množstvím chyb. V JS se na to původně vys*** a teď horko těžko na staré kolena zavádějí alespoň Worker.

perceptron

Re:Jak čekat na výsledky v Javascript
« Odpověď #9 kdy: 20. 11. 2015, 17:18:29 »
callbacky

ale to je grc

radsej promises

čumil

Re:Jak čekat na výsledky v Javascript
« Odpověď #10 kdy: 20. 11. 2015, 20:38:16 »
Uděláš z té náročné operace asynchronní operaci.

V tom se často chybuje. Hlavní smysl asynchronní funkce je právě ten, že během jejího vykonávání můžeš dělat svou jinou práci a nemusíš se o to nijak starat. Zavádělo se to právě proto, že multiplexovat to ručně tvým způsobem byla otrocká práce s množstvím chyb. V JS se na to původně vys*** a teď horko těžko na staré kolena zavádějí alespoň Worker.
Teda nevím v čem se chybuje ale přesně o tomhle jsem psal, práci vykonáváš v kusech a neblokuješ event loop od obsluhování eventů.

čumil

Re:Jak čekat na výsledky v Javascript
« Odpověď #11 kdy: 20. 11. 2015, 20:46:11 »
[...]Uděláš z té náročné operace asynchronní operaci. Jediné co budeš potřebovat je náročnou operaci rozsekat na "kroky" a tyto kroky poté vykonat postupně pomocí setTimeout [...]
Jenže setTimeout není úplně asynchronní. Jediná skutečně asynchronní věc na něm je ten časovač. Samotné provádění je ale sekvenční - když vyprší časovač, dokonční se aktuální operace a začne se provádět funkce nastavená v setTimeout. Ta se provede, a pak se obnoví původní běh. Pokud je více setTimeout nastaveno na stejný okamžik, tak se provádí sekvenčně, vždycky až když skript opustí předchozí callback.

Takže jediné smysluplné využití setTimeout v tuhle chvíli by bylo mít opravdu hodně malých kroků (max ~desítky ms na jeden) a mezi nimi mít nějaký rozumně velký časový úsek na ostatní věci, v závislosti na tom, jestli se takových náročných operací provádí víc najednou, na obsluhu GUI... Přidejme špetku generičnosti a jsme vlastně u implementace jednoduchého scheduleru pro jednoprocesorový systém, akorát místo HW časovače máme setTimeout...
No no, opravdu nejsem kokot abych setTimeout dal všude na stejný čas, to by se mi všechno do event loopu nacpalo pěkně za sebou a žádný zisk (neblokování event loopu) bych neměl.

Popíšu vlastní aplikaci. Měl jsem primitivní AI využívající evolučního algoritmu. Bohužel, ten žere tunu prostředků a protože byl v JS aplikaci, opravdu jsem nechtěl aby to celí zamrzlo. Tak jsem zpracování jednotlivých generací strčil do handleru setTimeout, přičemž po každé generaci sem to zopakoval s pauzou pár milisekund, díky tomu se v event loopu stihli odbavit ostatní eventy a appka nezamrzla a AI běžela.

Oznámení že provádění callbacku setTimeout je synchronní mne přišlo skoro jako urážka, sem snad debil ? ? ? :D


k

Re:Jak čekat na výsledky v Javascript
« Odpověď #12 kdy: 20. 11. 2015, 20:54:59 »
Teda nevím v čem se chybuje ale přesně o tomhle jsem psal, práci vykonáváš v kusech a neblokuješ event loop od obsluhování eventů.

Asynchronní funkce event loop z principu zablokovat nemůže, vůbec s ní neinteraguje, nemusíš se tedy o to starat s nějakými kusy. I kdybys v asynchronní funkci napsal while (true), v event loop ani UI to nepoznáš.

Oznámení že provádění callbacku setTimeout je synchronní mne přišlo skoro jako urážka, sem snad debil ? ? ? :D

Provádění callbacku od setTimeout je vzhledem k event loop synchronní záležitost.
Otázku na duševní zdraví ti zodpoví na adrese Ústavní 91, 181 02 Praha 8

čumil

Re:Jak čekat na výsledky v Javascript
« Odpověď #13 kdy: 20. 11. 2015, 21:32:17 »
Teda nevím v čem se chybuje ale přesně o tomhle jsem psal, práci vykonáváš v kusech a neblokuješ event loop od obsluhování eventů.

Asynchronní funkce event loop z principu zablokovat nemůže, vůbec s ní neinteraguje, nemusíš se tedy o to starat s nějakými kusy. I kdybys v asynchronní funkci napsal while (true), v event loop ani UI to nepoznáš.

Oznámení že provádění callbacku setTimeout je synchronní mne přišlo skoro jako urážka, sem snad debil ? ? ? :D

Provádění callbacku od setTimeout je vzhledem k event loop synchronní záležitost.
Otázku na duševní zdraví ti zodpoví na adrese Ústavní 91, 181 02 Praha 8
Okej, pudu tam na konzultaci ...

Async funkce v JS jsou realizovány (konkrétně zpracování jejich výstupu pro korektnost) pomocí event loopu. Výsledek je vždy poslán zpět ve formě eventu.

Já jsem z tvých odpovědí strašně zmatený, pokaždý mi přijdou že odpovídají na něco úplně jinýho než co právě řešíme a tak sem trošku vyvedený z míry. Samozřejmě že asynchronní funkce sama o sobě nemůže zablokovat event loop, její handler výsledku ale ano protože ten je vyvolaný v event loopu.

hu

Re:Jak čekat na výsledky v Javascript
« Odpověď #14 kdy: 20. 11. 2015, 22:15:32 »
No no, opravdu nejsem kokot abych setTimeout dal všude na stejný čas, to by se mi všechno do event loopu nacpalo pěkně za sebou a žádný zisk (neblokování event loopu) bych neměl.

Popíšu vlastní aplikaci. Měl jsem primitivní AI využívající evolučního algoritmu. Bohužel, ten žere tunu prostředků a protože byl v JS aplikaci, opravdu jsem nechtěl aby to celí zamrzlo. Tak jsem zpracování jednotlivých generací strčil do handleru setTimeout, přičemž po každé generaci sem to zopakoval s pauzou pár milisekund, díky tomu se v event loopu stihli odbavit ostatní eventy a appka nezamrzla a AI běžela.

Oznámení že provádění callbacku setTimeout je synchronní mne přišlo skoro jako urážka, sem snad debil ? ? ? :D

No to je krása. Takže máme OS s preemptivním multitaskingem, ten naplánuje browser, browser vytvoří vlákno interpretující JS a v důsledku doběhnutí event queue se občas odloží vykonávání toho vlákna voláním pollu nebo něčeho podobného. Když máme ve frontě timer event, tak se vlákno z pollu zas někdy třeba probudí, spočítá se 1+1, do event queue se flákne další timer event s arbitrární hodnotou takovou, aby se nám to moc nepotkávalo s obsluhou kliknutí na debilní tlačítko a doufáme, že se příště spočítá 1+2.

To je přesně technologie, kterou bych nasadil na implementaci AI. Ale debil nejsi. Až to budeš přepisovat do céčka, doporučuju něco v tomhle smyslu:
Kód: [Vybrat]
for( ; ; ) {
  if (debil_kliknul_na_button()) {
    usekni_mu_ruku(1);
  }
  usleep(random());
  krutoprisne_spocitej_dalsi_generaci_debilu();
}

Pro dosažení vyššího levelu nirvany do sebe vnoř víc takovejch smyček, čím víc inception tim pomalejc totiž běží čas.