Az az egyik gondom JS-el, hogy minden aszinkron. Ez amúgy praktikus, mert nem blokkol, viszont a kód elveszti a linearitását, és olvashatatlanabb lesz. Tehát mondjuk olyat akarok, hogy letöltök egy adatbázist, megnyitom, és futtatok egy lekérdezést. Azt nem tehetem meg így lineárisan, hanem a letöltés hív egy callback-et, amiben a db megnyitás hív egy callback-et, amiben a lekérdezés hív egy callback-et, ahol végre megjelenik az eredmény. De az egész vagy egymásba ágyazott névtelen függvények halmaza, vagy definiálhat az ember minden callback-nek külön fv.-t, a helyett, hogy ilyet írna:
dbfile = load(url);
db = db_open(dbfile);
result = db.query(...);
Erre jó lenne valami, akár valami cross-compileres megoldás is, hogy lineárisan lehessen írni a kódot, amit aztán átalakít ilyen callback-es formába.
Balazs Nadasdi (vélemény? mint JavaScript témában legkompetensebb ismerős :))
Hazaértem írok, de most még kerekezek
VálaszTörlésA Dart-os async Future mára már elég jó, ott lehet olyant mondani hogy valami()
VálaszTörlés.then((x) {})
.then((y) {})
.then((z) {})
.then((z2) {});
Azaz az egymásba ágyazható callback-ek helyett van egy szép lineáris kódod. Valaki azt mondta régebben, hogy ez a node.js-es projekt nagyon hasonlót csinál, de én nem néztem meg közelebbről:
https://github.com/coolaj86/futures
Van promise és a legtöbb linn tud vele mit kezdeni. De mér mindjárt otthon :-) csak pirosat kaptam.
VálaszTörlésIstvan Soos Azért ez sem a legszebb megoldás, mert itt meg a then-ek szabdalják szét a kódot. Illetve azt nem értem még, hogy mit ad vissza a then, amire a másik then-t hívod, és hol mondod meg neki, hogy akkor hívódjon meg, mikor letöltöttél valamit, aztán a következő akkor, mikor megnyitod a db-t, stb.
VálaszTörlésNah itthon.
VálaszTörlésEloszor is van az ugynevezett Promise. Ez azt mondja, hogy "Megigerem, hogy itt lesz valami". Aztan van success meg fail fuggvenye igy pl lancolhato is akar.
Sok (pl fs.*) lib-nek van Sync fuggvenye is. Ezen kivul a sajat cuccaidhoz csinalhatsz valami keretet amivel mondjuk megoldod, hogy User.findById(userId) es ez egy igerettel ter vissza.
Van sok ORM ami mar ezt biztositja szamodra, ha adatbazisrol van szo:
- http://bookshelfjs.org/
- http://knexjs.org/
Nekem viszont sok esetben fuggetlen keresekhez kell, amit meg az adatbazik libbel es az async segitsegevel meg is oldok. Pelda:
Oldal betoltesekor:
[kategorialista lekerdezese, cimkek lekerdezese, felhasznalo lekerdezese, adott tartalmanak lekerdezese], ha ez vegzett (async parallel kerdezes utani success fuggveny) rendereljuk le az oldalt.
Ezen kivul pedig en sose csinalok fo agban olyat (nah jo ritkan ha csak valami demohoz kell az anyag), hogy egymasba pakolok 4-5 callback-et. Altalaban ha ilyen a mertek akkor olyanokrol van szo amik amugy is osszetartoznak es csinalok inkabb egy kulon file-t, amiben van egy fuggveny mondjuk getUser(), ami visszater a userrel es a hozza tartozo dolgokkal. Abban lehet tobb egymasba agyazas, mert kommentelem es nagy esellyel ritkan nyulok hozza. A fo agamban meg csak 1 callback lesz. Lehet parametereztetni is, hogy pl amennyiben nem kell bizonyos adat, akkor a fuggveny ne hivjon kerjen tobbet, hanem terjen vissza azzal ami adott szinten van.
Teny neha kenyelmetlen, de sok esetben nem (legtobb esetben). Ez olyan, hogy mas nyelvekben is sok esetben kenyelmetlen minden losz@rnak egy class-t csinalni, vagy epp mindenhol lekerdezni adott dolgot, mert nem fer hozza es nem oldhato meg erdelmesen es ezert meg 3 class kell, hogy tudjon ferni.
Amugy meg pl tok logikus :)
VálaszTörlésElinditod az appot. Kapcsolodsz adatbazishoz, kiertelmezed a tobbi konfiguraciot, betoltod a szukseges dolgokat. Parhuzamosan. Ha mindegyik vegzett, akkor inditod a figyelest portra :)
Laszlo Fazekas A Dart-os Future.then() visszatérhet egy új Future-el, és akkor automatikusan láncolódnak. Itt egypár példa arra, hogy hogyan is néz ki, ha pl. masszívan aszinkron műveleteid vannak egymás után a tesztekben:
VálaszTörléshttps://github.com/agilord/riak_dart_client/blob/master/test/local_http_test.dart
Istvan Soos mondjuk azt nem ertem miert volt jo atnevezniuk a tok talalo nevu Promise-t Future-ra :)
VálaszTörlésBalazs Nadasdi De ezek mind ilyen áthidaló megoldások, és mindenhol kell legalább 1 callback. Én valami olyasmit tartanék szépnek, ahol minden eseménykezelő olyan mint ha külön thread-et indítana, amiben viszont lineárisan írhatod a dolgokat olyan fv,-ekkel, amik blokkolnak. Tehát ilyen, amit írtam:
VálaszTörlésdbfile = load(url);
db = db_open(dbfile);
result = db.query(...);
Ehhez mondjuk mindenképp valami előfordító kellene, ami ezt csinálja belőle:
load(url, function(dbfile) {
db_open(dbfile, function(db) {
db.query(..., function(result) { ... })
})
})
Ezt mondjuk fordító nélkül nem biztos, hogy meg lehet csinálni, de szerintem jópofa lenne egy ilyen js-js fordító, ami mondjuk figyeli, hogy @fvnév-el hívsz egy fv.-t, akkor így alakítja át.
Istvan Soos Na, akkor már a future-t értem. De a legelegánsabb szerintem az lenne, amit írtam. :)
VálaszTörlésLaszlo Fazekas szerintem felesleges :) Es meg mindig jobb mint a java, ahol 400 class-t csinalsz csak mert ugy fog mukodni es kevesebbol mar nem fer hozza mindenhez ^^. =P
VálaszTörlésLaszlo Fazekas Volt erről több vizsgálódás, arról is hogy mit lehet hatékonyan megcsinálni előfordítóval ill. mi az ami hatékonyan futtatható a VM-en. A legutolsó vélemény szerint a Dart-ban nem lesz előfordító, hanem úgynevezett async block-ok, ahol kb. lineáris felsorolással megcsinálhatod azt, amit pl. a Future láncolással. Az előfordítónak több hasfájása is van, pl. ha az egyik hívás nem csak egyetlen async műveletet generál, akkor nehéz megmondani helyesen, hogy hol van a scope-határ.
VálaszTörlésIstvan Soos Lehet, de ilyen egyszerű esetekre praktikus lenne. Több callback-re persze nem használható. Ezekről az async block-okról van valahol doksi?
VálaszTörlésBalazs Nadasdi Azért Java-val sem kell mindent agyament módon csinálni. Attól, hogy néhányan agyamenten használják, még nem a nyelv szar. :)
Én csak egy előadásra emlékszem kb. az idei Google IO előttről egy kicsivel, doksit nem láttam. Mivel még csak kísérleti buildekben van belőle futó példány, ezért még nem vennék belőle semmit sem biztosra :)
VálaszTörlés