Komentáře k článku

Zbavte se asynchronních callbacků v Node.js za pomocí generátorů

Asynchronní callbacky v Node.js jsou peklo. Každý, kdo v nodě něco kdy zkoušel napsat, to ví. Nové verze enginu V8 nám ale přináší některé novinky z ECMA6, které pomohou udělat asynchronní kód čitelný a jednoduchý, konkrétně mám na mysli generátory. V tomto článku si ukážeme techniku, která umožní psát asynchronní kód stejně čitelně, jako by byl synchronní.

Zpět na článek

41 komentářů k článku Zbavte se asynchronních callbacků v Node.js za pomocí generátorů:

        1. Pavel LangAutor příspěvku

          Re: Korektura
          Díky za opravu, občas to prostě uteče, většinou když se hledá vhodná formulace…

  1. jjjjj

    fibonacci postupnost
    k tej fibonacci postupnosti este jedna otazocka. ten generator mi stale bezi alebo po klucovom slove yield sa zastavi pokial nezavolam next()?

    1. Martin Hassman

      Re: fibonacci postupnost

      Zastavi, yield je v podstate takovy „return„, a po zavolani next() koprogram zase pokračuje.

  2. keff

    Garbage collection generatoru?
    Dobry den, hledal jsem, ale zatim marne – jak funguje GC u generatoru? Pokud budu mit nekonecny generator (napr. ten fibonacci), jak vi runtime kdy uz ho muze smazat? Nebo je nejaka konvence ze pokud vim ze generator uz nebudu potrebovat, tak ho necham dobehnout (napr. ve fib. generatoru mu z kodu poslu jako hodnotu false, nebo mu dam vyjimku)?

    1. Martin Hassman

      Re: Garbage collection generatoru?

      Nevím, ale je to zajímavý dotaz, tak jsem chvíli přemýšlel a Googlil a zdá se, že to (v jiných jazycích) řeší klasicky pomocí referencí, tak bych tipoval, že to v JS bude podobné – jakmile na generátor nebude směřovat žádná reference, musí být odklizen. Každopádně generátor má i metodu close(), který zajistí jeho ukončení a spuštění bloku finally, pokud je v něm definován, viz http://wiki.ecmascript.org/doku.php?id=harmony:generators#methodclose

      1. Pavel LangAutor příspěvku

        Re: Garbage collection generatoru?
        Typoval bych, že GC funguje tak, jak martin popsal, tedy se uklidí jako jakýkoliv jiný objekt, když není již nikde referencován.

        1. Pavel LangAutor příspěvku

          Re: Garbage collection generatoru?
          Metodu close generátor ve V8 generátor nemá a na blok finally se spoléhat dá pouze při přirozeném ukončení iterace nebo při vyjímce zaslané generátoru pomocí metody throw.
          Na GC se však dá spolehnout, že zdroje uvolní, viz příklad: generator-try-finally.js

          Tento kód má následující výstup:

          $ node --expose-gc --harmony generator-try-finally.js
          Allocationg 1048576 bytes as soon as setInterval(.., 0) can
          Starting with: { rss: 13869056, heapTotal: 8358912, heapUsed: 3323648 }
          ....
           { rss: 18173952, heapTotal: 8358912, heapUsed: 3534568 } { rss: 14127104, heapTotal: 10456064, heapUsed: 3454224 }
          ..
           { rss: 15474688, heapTotal: 10456064, heapUsed: 3507056 } { rss: 13717504, heapTotal: 10456064, heapUsed: 3468752 }
          ...
           { rss: 16687104, heapTotal: 10456064, heapUsed: 3497320 } { rss: 14766080, heapTotal: 10456064, heapUsed: 3214864 }
          ...
           { rss: 16654336, heapTotal: 10456064, heapUsed: 3242960 } { rss: 14766080, heapTotal: 10456064, heapUsed: 3183240 }
          ...
           { rss: 16654336, heapTotal: 10456064, heapUsed: 3211024 } { rss: 14766080, heapTotal: 10456064, heapUsed: 3177512 }
          ..
          Error: Error: Interrupt at 2
          Finnaly: at 2
           { rss: 16654336, heapTotal: 10456064, heapUsed: 3224864 } { rss: 14790656, heapTotal: 10456064, heapUsed: 3190704 }
          ....
           { rss: 17760256, heapTotal: 10456064, heapUsed: 3223272 } { rss: 13746176, heapTotal: 10456064, heapUsed: 3193432 }
          ...
           { rss: 16715776, heapTotal: 10456064, heapUsed: 3221432 } { rss: 14794752, heapTotal: 10456064, heapUsed: 3193376 }
          ..
          Finnaly: at 4.
           { rss: 17764352, heapTotal: 10456064, heapUsed: 3228968 } { rss: 13746176, heapTotal: 10456064, heapUsed: 3194424 }
          ...
           { rss: 16715776, heapTotal: 10456064, heapUsed: 3222424 } { rss: 14794752, heapTotal: 10456064, heapUsed: 3194368 }
          ...
           { rss: 16683008, heapTotal: 10456064, heapUsed: 3224568 } { rss: 14798848, heapTotal: 10456064, heapUsed: 3195936 }
          ..
           { rss: 15605760, heapTotal: 10456064, heapUsed: 3224248 } { rss: 13750272, heapTotal: 10456064, heapUsed: 3196040 }
          
          Error: Error: Interrupt at 2
          Finnaly: at 2...
           { rss: 17801216, heapTotal: 10456064, heapUsed: 3240480 } { rss: 13750272, heapTotal: 10456064, heapUsed: 3201128 }
          ...
           { rss: 16719872, heapTotal: 10456064, heapUsed: 3229192 } { rss: 14798848, heapTotal: 10456064, heapUsed: 3201136 }
          ...
           { rss: 16687104, heapTotal: 10456064, heapUsed: 3235416 } { rss: 16687104, heapTotal: 10456064, heapUsed: 3206312 }
          ...
           { rss: 16736256, heapTotal: 10456064, heapUsed: 3270584 } { rss: 15015936, heapTotal: 10456064, heapUsed: 3230488 }
          ...
           { rss: 16904192, heapTotal: 10456064, heapUsed: 3258384 } { rss: 15024128, heapTotal: 10456064, heapUsed: 3230488 }
          ...
           { rss: 16912384, heapTotal: 10456064, heapUsed: 3264440 } { rss: 15024128, heapTotal: 10456064, heapUsed: 3233576 }
          .
          Finnaly: at 4.
          Error: Error: Interrupt at 2
          Finnaly: at 2.
           { rss: 19075072, heapTotal: 10456064, heapUsed: 3276752 } { rss: 14946304, heapTotal: 10456064, heapUsed: 3234120 }
          ...
           { rss: 16834560, heapTotal: 10456064, heapUsed: 3264816 } { rss: 14950400, heapTotal: 10456064, heapUsed: 3235144 }
          ...
           { rss: 16838656, heapTotal: 10456064, heapUsed: 3269560 } { rss: 15986688, heapTotal: 10456064, heapUsed: 3238856 }
          ...
           { rss: 16818176, heapTotal: 10456064, heapUsed: 3266952 } { rss: 14929920, heapTotal: 10456064, heapUsed: 3236472 }
          ...
           { rss: 16904192, heapTotal: 10456064, heapUsed: 3308168 } { rss: 13930496, heapTotal: 10456064, heapUsed: 3265296 }
          ...
           { rss: 16900096, heapTotal: 10456064, heapUsed: 3293392 } { rss: 13930496, heapTotal: 10456064, heapUsed: 3265672 }
          ...
          Error: Error: Interrupt at 2
          Finnaly: at 2
           { rss: 17981440, heapTotal: 10456064, heapUsed: 3301176 } { rss: 13930496, heapTotal: 10456064, heapUsed: 3269016 }
          ...
           { rss: 16900096, heapTotal: 10456064, heapUsed: 3297240 } { rss: 13930496, heapTotal: 10456064, heapUsed: 3269096 }
          ..
           { rss: 15818752, heapTotal: 10456064, heapUsed: 3295696 } { rss: 13930496, heapTotal: 10456064, heapUsed: 3269072 }
          ..
          Finnaly: at 4..
           { rss: 18792448, heapTotal: 10456064, heapUsed: 3302848 } { rss: 13930496, heapTotal: 10456064, heapUsed: 3270576 }
          ...
           { rss: 16900096, heapTotal: 10456064, heapUsed: 3298584 } { rss: 13930496, heapTotal: 10456064, heapUsed: 3270464 }
          ...
           { rss: 16900096, heapTotal: 10456064, heapUsed: 3310328 } { rss: 16900096, heapTotal: 10456064, heapUsed: 3282824 }
          ..
           { rss: 15953920, heapTotal: 10456064, heapUsed: 3403032 } { rss: 13942784, heapTotal: 10456064, heapUsed: 3342056 }
          .
          Error: Error: Interrupt at 2
          Finnaly: at 2..
           { rss: 17989632, heapTotal: 10456064, heapUsed: 3386512 } { rss: 13922304, heapTotal: 10456064, heapUsed: 3348000 }
          ....
           { rss: 17973248, heapTotal: 10456064, heapUsed: 3373624 } { rss: 13922304, heapTotal: 10456064, heapUsed: 3348000 }
          ...
           { rss: 16891904, heapTotal: 10456064, heapUsed: 3372336 } { rss: 13922304, heapTotal: 10456064, heapUsed: 3347944 }
          ..
           { rss: 15810560, heapTotal: 10456064, heapUsed: 3370992 } { rss: 13922304, heapTotal: 10456064, heapUsed: 3345864 }
          ...
           { rss: 16891904, heapTotal: 10456064, heapUsed: 3370200 } { rss: 13922304, heapTotal: 10456064, heapUsed: 3345920 }
          ...
          Finnaly: at 4.
           { rss: 18784256, heapTotal: 10456064, heapUsed: 3374088 } { rss: 13922304, heapTotal: 10456064, heapUsed: 3347448 }
          .
          Error: Error: Interrupt at 2
          Finnaly: at 2..
           { rss: 17973248, heapTotal: 10456064, heapUsed: 3379248 } { rss: 13922304, heapTotal: 10456064, heapUsed: 3350760 }
          ...
           { rss: 16891904, heapTotal: 10456064, heapUsed: 3375096 } { rss: 13922304, heapTotal: 10456064, heapUsed: 3351080 }
          ...
           { rss: 16891904, heapTotal: 10456064, heapUsed: 3379080 } { rss: 13922304, heapTotal: 10456064, heapUsed: 3352232 }
          ...
           { rss: 16891904, heapTotal: 10456064, heapUsed: 3376568 } { rss: 13922304, heapTotal: 10456064, heapUsed: 3352232 }
          ...
           { rss: 16891904, heapTotal: 10456064, heapUsed: 3376568 } { rss: 13922304, heapTotal: 10456064, heapUsed: 3352232 }
          ...
           { rss: 16891904, heapTotal: 10456064, heapUsed: 3382248 } { rss: 13922304, heapTotal: 10456064, heapUsed: 3356112 }
          .
          Error: Error: Interrupt at 2
          Finnaly: at 2..
           { rss: 17973248, heapTotal: 10456064, heapUsed: 3390224 } { rss: 13914112, heapTotal: 10456064, heapUsed: 3355360 }
          ...
           { rss: 16883712, heapTotal: 10456064, heapUsed: 3388080 } { rss: 13914112, heapTotal: 10456064, heapUsed: 3359912 }
          ..
          Finnaly: at 4.
           { rss: 17965056, heapTotal: 10456064, heapUsed: 3386808 } { rss: 13914112, heapTotal: 10456064, heapUsed: 3360648 }
          ...
           { rss: 16883712, heapTotal: 10456064, heapUsed: 3384984 } { rss: 13914112, heapTotal: 10456064, heapUsed: 3358224 }
          ...
           { rss: 16883712, heapTotal: 10456064, heapUsed: 3382560 } { rss: 13914112, heapTotal: 10456064, heapUsed: 3358224 }
          ..
           { rss: 15802368, heapTotal: 10456064, heapUsed: 3386064 } { rss: 13914112, heapTotal: 10456064, heapUsed: 3360680 }
          ...
          Error: Error: Interrupt at 2
          Finnaly: at 2.
           { rss: 19841024, heapTotal: 10456064, heapUsed: 3446488 } { rss: 14032896, heapTotal: 10456064, heapUsed: 3391496 }
          ...
           { rss: 17002496, heapTotal: 10456064, heapUsed: 3415960 } { rss: 14049280, heapTotal: 10456064, heapUsed: 3382616 }
          ....
           { rss: 18100224, heapTotal: 10456064, heapUsed: 3408240 } { rss: 14049280, heapTotal: 10456064, heapUsed: 3382672 }
          ...
           { rss: 17018880, heapTotal: 10456064, heapUsed: 3409000 } { rss: 14049280, heapTotal: 10456064, heapUsed: 3383912 }
          ..Should now terminate
          ....
          Finnaly: at 4..
          Error: Error: Interrupt at 2
          Finnaly: at 2....................
          Error: Error: Interrupt at 2
          Finnaly: at 2.......
          Finnaly: at 4..........
          Error: Error: Interrupt at 2
          Finnaly: at 2.............
          Finnaly: at 4...
          Error: Error: Interrupt at 2
          Finnaly: at 2................
          Error: Error: Interrupt at 2
          Finnaly: at 2......
          Finnaly: at 4...........
          Error: Error: Interrupt at 2
          Finnaly: at 2......
           { rss: 129478656, heapTotal: 10456064, heapUsed: 3604480 } { rss: 80273408, heapTotal: 10456064, heapUsed: 3392840 }
          
      2. Jiří Knesl

        Re: Garbage collection generatoru?
        No jo, jenže co když je generátor globálně přístupná funkce?
        Tam bude vývojář nejspíš odkázán na ruční volání close()

        1. Martin Hassman

          Re: Garbage collection generatoru?

          I takovou globální funkci můžeš zrušit třeba jejím předefinováním. Ale jinak ano, close v takovýchhle případech ideálně poslouží.

  3. Pavel LangAutor příspěvku

    Co dál?
    Další díl bude jistě prezentovat framework koa, ale chtěl bych vědět, zda chcete mysql (nebo relační databáze, mám raději postgres) nebo spíš mongo, každopádně na session se hodí nejlépe redis. Tím apeluji na Vás, čtenáře! Tak čekám bouřlivou diskuzi…

    1. fos4

      Re: Co dál?
      Díky za díl a těším se na dalším. Rád bych byl za mongo/mongoosejs – neboť s tím nepracuji každý den..

      1. Pavel LangAutor příspěvku

        Re: Co dál?
        Dobrá tedy, chtěl jsem ukázat i MySQL připojení protože v tom je u nás v republice uložená většina dat, uvidíme jak vyjde čas a co stihnu sepsat..

        1. Ondra Melkes

          Re: Co dál?
          Co třeba relační databázi (je celkem jedno zda postgree, nebo mysql/maria) s právě zmíněným redisem jako session a cache?

          1. Pavel LangAutor příspěvku

            Re: Celkem zajímavé srovnání Nette a NodeJs
            Podobná srovnání mi přijdou nesmyslná, obzvlášť když dané technologie fungují na úplně jiných principech (long living application vs onetime script)

              1. Ondra Melkes

                Re: Celkem zajímavé srovnání Nette a NodeJs
                Myslím že je to špatné… porovnávat by ještě šlo platformu, tedy NodeJs vs PHP ale ne platformu a framework, tedy NodeJs vs Nette.

                1. Martin Hassman

                  Re: Celkem zajímavé srovnání Nette a NodeJs

                  V tomhle s vámi Pavle a Ondřeji nemůžu souhlasit. Ale to je tím, že já nesouhlasím s běžným rčením „Nelze srovnávat jablka s hruškami.“ Pro mnohé je tohle axiom, který je pravdivý a z toho se pak odvíjí třeba i ono srovnání Node vs Nette. Podle mě je tohle tvrzení nepravdivé, vyvrátím ho snadno během jediného nákupu, kdy se budu rozhodovat mezi nákupem jablek a hrušek a jejich srovnání se tak prostě nevyhnu (a moc nevěřím, že to někdo dokáže).

                  Podle me je zcela regulérní srovnávat Node a Nette, pokud se z onoho srovnání nebudme snažit vyčíst to, co tam není. Ono můžete klidně srovnávat třeba tvorbu webu v Node.js třeba s vylepením billboardu u dálnice – pro někoho i taková otázka může mít význam a odpověď může také dávat smysl: Zvýší se návštěvnost mé kavárny víc vylepením billboardu nebo vytvořením microsity v Node.js? Je to správná otázka. Pochopitelně z odpovědi bychom vůbec nezjistili, zda je Node.js lepší/horší než billboard, takový závěr by byl špatný. Ale otázka je zcela správná jako majitelk kavárny si ji klidně mohu klást.

                  Stejně tak ze srovnání Nette a Node.js nezjistíme, kdo z nich je lepší, ale jak jsem si právě přečetl v úvodu té diplomky, cíl byl hlavně studijní a z toho pohledu je to správná otázka. Nečetl jsem celou práci, nevím jaká je a nehodnotím ji, jen jsem se podíval do závěru a vidím tam např. že „Node má horší dokumentaci“ – to může být korektní závěr, nevím zda je pravdivý, po nedávném rozhovoru s Davidem mám naopak pocit, že je težké mít horší dokumentaci než Nette, ale může to být jen dojem. Ale je to validní závěr, který můžeme potvrdit anebo zpochybnit (nedělám ani jedno, nesrovnával jsem ty dokumentace) a můžeme z toho i vyvozovat (jak ona práce dělá), že XY je horší pro začátečníky, protože má horší dokumentaci.

                  Dokud to budeme brát takhle a nebude z toho vyvozovatm že XY je horší (protože to už je jiný výrok a jeho pravdivost z takového porovnání ověřit nejde), tak je vše v pořádku.

                  Stejně tak můžu tvrdit, že mám radši jablka a tudíž jablka jsou pro mě lepší, což ovšem nic neříká o tom, zda jablka jsou lepší než hrušky.

                  Z toho pohledu mi takové zadání přijde v pořádku. Ano, je to akademické, možná nepraktické a v rukou „amatéra“ mohou z takové diplomky vyplynout třeba zcela zcestné závěry, ale to srovnávání samo o sobě je v pořádku.

                  1. Pavel LangAutor příspěvku

                    Re: Celkem zajímavé srovnání Nette a NodeJs

                    V tomhle s vámi Pavle a Ondřeji nemůžu souhlasit. Ale to je tím, že já
                    nesouhlasím s běžným rčením „Nelze srovnávat jablka s hruškami.“ Pro
                    mnohé je tohle axiom, který je pravdivý a z toho se pak odvíjí třeba i
                    ono srovnání Node vs Nette.

                    Promiň že jsem ti zodělil odstavec:

                    Podle mě je tohle tvrzení nepravdivé,
                    vyvrátím ho snadno během jediného nákupu, kdy se budu rozhodovat mezi
                    nákupem jablek a hrušek a jejich srovnání se tak prostě nevyhnu (a moc
                    nevěřím, že to někdo dokáže).

                    Ano, já se nesnažím tento přístup prodat, ale vysvětlit. Ve chvíli kdy někdo nakupuje, platí tvá první část odstavce, proto si myslím, že při vzetí v úvahu neznalosti některých čtenářů buď jedné, nebo druhé technologie, se mi jeví podobná studie jako nevhodná. Pokud chce někdo prodávat své názory, tak prosím, ale já chci vysvětlit novou technologii.

                    Podle me je zcela regulérní srovnávat Node a Nette, pokud se z onoho
                    srovnání nebudme snažit vyčíst to, co tam není. Ono můžete klidně
                    srovnávat třeba tvorbu webu v Node.js třeba s vylepením billboardu u
                    dálnice – pro někoho i taková otázka může mít význam a odpověď může
                    také dávat smysl: Zvýší se návštěvnost mé kavárny víc vylepením
                    billboardu nebo vytvořením microsity v Node.js? Je to správná otázka.
                    Pochopitelně z odpovědi bychom vůbec nezjistili, zda je Node.js
                    lepší/horší než billboard, takový závěr by byl špatný. Ale otázka je
                    zcela správná jako majitel kavárny si ji klidně mohu klást.

                    Mám spor. Odkazovaná studie se snaží srovnávat tvorbu jakblek a jablek za pomocí hrušní a jabloní. Toto je krajně nevhodné, je třeba srovnávat surové PHP, surové Ruby, surové Node.js; nebo Nette versus RoR versus connect+express+locomotive. Pak je ale velice nešťastně hodnoceno Node vs Nette. To jej jako srovnávat spoustu neuspořádaných funkcí, pojmenovaných podle bindingu na nativní (většinou C nebo C++) knihovnu oproti velice tenoučké vrstvě uspořádané do core modulů. Srovnejte si třeba CPAN a NPM, to je pak v pořádku.

                    Stejně tak ze srovnání Nette a Node.js nezjistíme, kdo z nich je
                    lepší, ale jak jsem si právě přečetl v úvodu té diplomky, cíl byl
                    hlavně studijní a z toho pohledu je to správná otázka. Nečetl jsem
                    celou práci, nevím jaká je a nehodnotím ji, jen jsem se podíval do
                    závěru a vidím tam např. že „Node má horší dokumentaci“ – to může být
                    korektní závěr, nevím zda je pravdivý, po nedávném rozhovoru s Davidem
                    mám naopak pocit, že je težké mít horší dokumentaci než Nette, ale
                    může to být jen dojem. Ale je to validní závěr, který můžeme potvrdit
                    anebo zpochybnit (nedělám ani jedno, nesrovnával jsem ty dokumentace)
                    a můžeme z toho i vyvozovat (jak ona práce dělá), že XY je horší pro
                    začátečníky, protože má horší dokumentaci.

                    Z vlastních zkušeností, pokud hledám pro nette, nenacházím moc rozšíření.
                    Pokud hledám pro node.js, nacházím jich víc, ale více zaměřených určitým směrem. Moc nesouhlasím s kopírováním klasického objektového vzoru ve smyslu C++, Javy a C# do JavaScriptu, který má prototypovou dědičnost. V těchto jazycích je klonování návrhový vzor, který musí implementovat metodu clone(). V JavaScriptu existuje prototyp objektu, který přebírá roli implementátora – virtuální metody nebo i proměnné.

                    Koncept „volajícího“ funkce přístupného přez „this“ je někdy matoucí, ale při rozumném použití vynikající (a to že vyniká občas dělá problém… ).

                    Dokud to budeme brát takhle a nebude z toho vyvozovatm že XY je horší
                    (protože to už je jiný výrok a jeho pravdivost z takového porovnání
                    ověřit nejde), tak je vše v pořádku.

                    To mě na dané studii vadí, viz odkaz na hrušně a jabloně. Polovina je citace „školních známek“ za často nerelevantní či subjektivní nebo nepochopené (rozuměj nesprávně použité vzory daného jazyka) srovnání implementační náročnosti, z čehož vyplívá horší čitelnost a porozumnění kódu ze strany subjektu s jiným intuitivním modelem celého problému.

                    Stejně tak můžu tvrdit, že mám radši jablka a tudíž jablka jsou pro mě
                    lepší, což ovšem nic neříká o tom, zda jablka jsou lepší než hrušky.

                    Z toho pohledu mi takové zadání přijde v pořádku. Ano, je to
                    akademické, možná nepraktické a v rukou „amatéra“ mohou z takové
                    diplomky vyplynout třeba zcela zcestné závěry, ale to srovnávání samo
                    o sobě je v pořádku.

                    Proto jsem vyjádřil znepokojení, ale samozřejmě, až takové práce za 10 let budou vycházet o Node.js jako ověřené (prověřené) praxí a názory, nebudu se divit :-)

                  2. Ondra Melkes

                    Re: Celkem zajímavé srovnání Nette a NodeJs
                    Pozor, ono má smysl srovnávat hrušku s jablkem, ale nevím jak velký má smysl srovnávat hrušku s jabloní.

                    Neboli, jako majitel kavárny porovnám bilboard s webstránkou, nebo reklamou v rádiu. Ale už mě jako majitele nezajímá to jestli bude udělaná v Angularu, nebo Nette, zda běží nad Javascriptem, nebo nad PHP.

                    Naopak jako programátora mě velmi zajímá použitá technologie a proto chci rozumě porovnat nástroje. Můžu porovnat vývoj nad čistým NodeJs s vývojem nad PHP+Nette, ale měl bych obojí dobře znát, používat best-practicies. A porovnávat alespoň s čistým Node bez MVC. Protože pak není patrné co vlastně porovnává – Locomitive? Node? Jiný z použitých balíčků?
                    Odkazovanou studii jsem čelt trochu víc než jen úvod se závěrem a právě to mi na ní vadí. Autor zná PHP + Nette, Node a Javascript méně.

                    A tímto se dostávám k tomu že bych neměl porovnávat hrušku s jabloní o které tvrdím že je to jablko. Jak by celé srovnání dopadlo, když by místo Locomotive použil třeba SailJs?
                    Nebylo by dobré na úvod zmínit menší zkušenost autora s Node? Minimálně je vhodné v úvodu zmínit, že se jedná o platformu PHP a Nete, kterou porovnávám s NodeJs a MVC frameworkem Locomotive.

                    1. Martin Hassman

                      Re: Celkem zajímavé srovnání Nette a NodeJs

                      Pavle a Ondřeji, díky za vysvětlení, myslím, že vás teď chápu o něco líp. Přesto nedokážu s vámi souhlasit, z pohledu zadavatele tématu mi přijde pokus o takové srovnání v pořádku. Nicméně nechci obhajovat tu konkrétní práci, to nebylo mým cílem, ani jsem ji na to pořádně nečetl.

    1. jlx

      Re: Co používat pro vývoj v začátcích?
      Virtual box snad ani není potřeba. V Linuxu a v OSX stačí prostě stáhnout binárku z http://nodejs.org/download/ a vybalit do home adresáře (stačí jenom /bin a /lib). Pak ještě mrknout do ~/.profile, jestli je tam cesta do ~/bin. Pokud ne, tak doplnit
      PATH="$HOME/bin:$PATH"

      Takhle to používám s úspěchem lokálně a občas i na serveru. V package systémech bývá většinou dost zastaralá verze. Pro Windows úplně netušim, i když tam je zase k dispozici instalátor.

      1. Jeník

        Re: Co používat pro vývoj v začátcích?
        Chápu, ale co v případě, že používám php + mysql, postgre na osx?
        Připadá mi, že pak moc drátuji a může dojít k konfliktům.

        1. jlx

          Re: Co používat pro vývoj v začátcích?
          Toho bych se nebál. Celej NodeJS se skládá ze dvou spustitelných souborů („bin/node“ a „bin/npm“) a knihovny modulů („lib/*“) – takže není moc míst, kde by ten konflikt mohl nastat. A smazat z home adresáře to jde vždycky..

  4. Jan Prachař

    Pointa článku mi přijde dost zavádějící. Asynchronních callbacků jsem se nezbavil díky generátorům, ale díky thunkům a funkci co. Abych podpořil své tvrzení argumenty, tak tento příklad uveděný ve článku

    co(function *() {
        return (yield read('./generator1.js', { encoding: 'utf-8' })) +
            (yield read('./generator2.js', { encoding: 'utf-8' }));
    })(function(err, result) {
        console.log(result);
    });
    

    lze jednoduše přepsat bez použití generátorů takto:

    co2(function () {
        return [read('./generator1.js', { encoding: 'utf-8' }),
            read('./generator2.js', { encoding: 'utf-8' })];
    }).then(function(err, result) {
        console.log(result.join());
    });
    

    Přičemž funkce co2 bude vypadat nějak takto:

    function co2(fn) {
        var i = 0, results = [];
        fn = fn();
        return new Promise(function(resolve, reject) {
            next(fn[i++]);
            function next(ret) {
               ret(function (err, res) {
                   if (err) return reject(err);
                   results.push(res);
                   if (i >= fn.length) return resolve(results);
                   next(fn[i++]);
               });
            }
        });
    }
    
      1. Pavel LangAutor příspěvku

        Re: Zavádějící pointa
        Promisy jsou klasickým řešením, generátory naproti tomu umožňují zápis ve stylu async await

    1. Pavel LangAutor příspěvku

      Re:
      Nezapomínej na výhodu, kterou dává generátor díky klíčovému slovu yield, tedy pozastavit vykonávání funkce-generátoru dokud se nezpracují asynchronní úlohy.

Napsat komentář

Tato diskuse je již příliš stará, pravděpodobně již vám nikdo neodpoví. Pokud se chcete na něco zeptat, použijte diskusní server Devel.cz

Zdroj: https://www.zdrojak.cz/?p=11277