Skip to content
Mithril.js 2
Main Navigation ÚtmutatóAPI

magyar

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština

magyar

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština

Megjelenés

Sidebar Navigation

API

Alapvető API

m(selector, attributes, children)

render(element, vnodes)

mount(root, component)

route(root, defaultRoute, routes)

request(options)

parseQueryString(string)

buildQueryString(object)

buildPathname(object)

parsePathname(string)

trust(html)

fragment(attrs, children)

redraw()

censor(object, extra)

Opcionális API

stream()

Útmutató

Ezen az oldalon

stream() ​

Leírás ​

A Stream egy reaktív adatszerkezet, amely a táblázatkezelő alkalmazások celláihoz hasonlóan működik.

Egy táblázatban, ha A1 = B1 + C1, akkor a B1 vagy C1 értékének megváltoztatása automatikusan megváltoztatja az A1 értékét.

Hasonlóképpen, a streamek függhetnek más streamektől, így az egyik stream értékének megváltoztatása automatikusan frissíti a másik stream értékét. Ez akkor hasznos, ha költséges számításaid vannak, és csak akkor szeretnéd futtatni őket, amikor feltétlenül szükséges, például nem minden újrarajzoláskor.

A streamek nem részei a Mithril.js alapvető terjesztésének. A Streams modul hozzáadásához használd:

javascript
var Stream = require('mithril/stream');

A modult közvetlenül is letöltheted, ha a környezeted nem támogatja a csomagkezelő eszközláncot:

html
<script src="https://unpkg.com/mithril/stream/stream.js"></script>

Ha közvetlenül <script> taggel töltöd be (nem pedig require-rel), a stream könyvtár window.m.stream néven lesz elérhető. Ha a window.m már definiálva van (pl. mert a fő Mithril.js scriptet is használod), akkor a meglévő objektumhoz fog kapcsolódni. Ellenkező esetben létrehoz egy új window.m-et. Ha a streameket a Mithril.js-sel együtt szeretnéd használni nyers script tagekként, akkor a Mithril.js-t a mithril/stream elé kell illesztened az oldalba, mert a mithril egyébként felülírja a mithril/stream által definiált window.m objektumot. Ez nem okoz problémát, ha a könyvtárak CommonJS modulokként vannak felhasználva (require(...) használatával).

Szignatúra ​

Stream létrehozása

stream = Stream(value)

ArgumentumTípusKötelezőLeírás
valueanyNemHa meg van adva, a stream értéke erre lesz beállítva.
visszatérStreamVisszaad egy streamet.

Hogyan kell olvasni a szignatúrákat

Statikus tagok ​

Stream.combine ​

Létrehoz egy számított streamet, amely reaktívan frissül, ha bármelyik forrásstreamje frissül. Lásd a streamek kombinálása részt.

stream = Stream.combine(combiner, streams)

ArgumentumTípusKötelezőLeírás
combiner(Stream..., Array) -> anyIgenLásd a combiner argumentum leírását.
streamsArray<Stream>IgenA kombinálandó streamek listája.
visszatérStreamVisszaad egy streamet.

Hogyan kell olvasni a szignatúrákat

combiner ​

Meghatározza, hogyan jön létre egy számított stream értéke. Lásd a streamek kombinálása részt.

any = combiner(streams..., changed)

ArgumentumTípusKötelezőLeírás
streams...Streams felsorolásaNemNulla vagy több stream felsorolása, amelyek a stream.combine második argumentumaként átadott streameknek felelnek meg.
changedArray<Stream>IgenA frissítés által érintett streamek listája.
visszatéranyVisszaad egy számított értéket.

Hogyan kell olvasni a szignatúrákat

Stream.merge ​

Létrehoz egy streamet, amelynek értéke egy tömb, ami a bemeneti streamek értékeit tartalmazza.

stream = Stream.merge(streams)

ArgumentumTípusKötelezőLeírás
streamsArray<Stream>IgenStreamek listája.
visszatérStreamVisszaad egy streamet, amelynek értéke a bemeneti streamek értékeinek tömbje.

Hogyan kell olvasni a szignatúrákat

Stream.scan ​

Létrehoz egy új streamet, amely meghívja a függvényt a stream minden értékére egy akkumulátorral és a bejövő értékkel.

Ne feledd, hogy megakadályozhatod a függő streamek frissítését, ha a stream.SKIP speciális értéket adod vissza az akkumulátor függvényen belül.

stream = Stream.scan(fn, accumulator, stream)

ArgumentumTípusKötelezőLeírás
fn(accumulator, value) -> result |SKIPIgenEgy függvény, amely egy akkumulátor és egy érték paramétert vesz fel, és egy azonos típusú új akkumulátor értéket ad vissza.
accumulatoranyIgenAz akkumulátor kezdőértéke.
streamStreamIgenA stream, amely az értékeket tartalmazza.
visszatérStreamVisszaad egy új streamet, amely az eredményt tartalmazza.

Hogyan kell olvasni a szignatúrákat

Stream.scanMerge ​

Egy streamek és scan függvények párjainak tömbjét veszi fel, és az adott függvényekkel egyesíti az összes streamet egyetlen streammé.

stream = Stream.scanMerge(pairs, accumulator)

ArgumentumTípusKötelezőLeírás
pairsArray<[Stream, (accumulator, value) -> value]>IgenEgy streamek és scan függvények párjainak tömbje.
accumulatoranyIgenAz akkumulátor kezdőértéke.
visszatérStreamVisszaad egy új streamet, amely az eredményt tartalmazza.

Hogyan kell olvasni a szignatúrákat

Stream.lift ​

Létrehoz egy számított streamet, amely reaktívan frissül, ha bármelyik forrásstreamje frissül. Lásd a streamek kombinálása részt. A combine-tól eltérően itt a bemeneti streamek argumentumként vannak felsorolva (tömb helyett), és a callback függvény a streamek értékeit kapja meg, nem magukat a streameket. Ez általában könnyebben kezelhető az alkalmazások számára, mint a combine.

stream = Stream.lift(lifter, stream1, stream2, ...)

ArgumentumTípusKötelezőLeírás
lifter(any...) -> anyIgenLásd a lifter argumentum leírását.
streams...Streams listájaIgenA liftelendő streamek.
visszatérStreamVisszaad egy streamet.

Hogyan kell olvasni a szignatúrákat

lifter ​

Meghatározza, hogyan jön létre egy számított stream értéke. Lásd a streamek kombinálása részt.

any = lifter(streams...)

ArgumentumTípusKötelezőLeírás
streams...Streams felsorolásaNemNulla vagy több érték felsorolása, amelyek a stream.lift számára átadott streamek értékeinek felelnek meg.
visszatéranyVisszaad egy számított értéket.

Hogyan kell olvasni a szignatúrákat

Stream.SKIP ​

Egy speciális érték, amely visszaadható a stream callbackeknek a downstream-ek végrehajtásának kihagyásához.

Stream["fantasy-land/of"] ​

Ez a metódus funkcionálisan azonos a stream-mel. A Fantasy Land Applicative specifikációjának való megfelelés érdekében létezik. További információkért lásd a Mi az a Fantasy Land részt.

stream = Stream["fantasy-land/of"](value)

ArgumentumTípusKötelezőLeírás
valueanyNemHa meg van adva, a stream értéke erre lesz beállítva.
visszatérStreamVisszaad egy streamet.

Példány tagok ​

stream.map ​

Létrehoz egy függő streamet, amelynek értéke a callback függvény eredményére van állítva. Ez a metódus a stream["fantasy-land/map"] aliasa.

dependentStream = stream().map(callback)

ArgumentumTípusKötelezőLeírás
callbackany -> anyIgenEgy callback, amelynek visszatérési értéke a stream értéke lesz.
visszatérStreamVisszaad egy streamet.

Hogyan kell olvasni a szignatúrákat

stream.end ​

Egy ko-függő stream, amely megszünteti a függő streamek regisztrációját, ha igaz értékre van állítva. Lásd a lezárt állapot részt.

endStream = stream().end

stream["fantasy-land/of"] ​

Ez a metódus funkcionálisan azonos a stream-mel. A Fantasy Land Applicative specifikációjának való megfelelés érdekében létezik. További információkért lásd a Mi az a Fantasy Land részt.

stream = stream()["fantasy-land/of"](value)

ArgumentumTípusKötelezőLeírás
valueanyNemHa meg van adva, a stream értéke erre lesz beállítva.
visszatérStreamVisszaad egy streamet.

stream["fantasy-land/map"] ​

Létrehoz egy függő streamet, amelynek értéke a callback függvény eredményére van állítva. Lásd a streamek láncolása részt.

Ez a metódus a Fantasy Land Applicative specifikációjának való megfelelés érdekében létezik. További információkért lásd a Mi az a Fantasy Land részt.

dependentStream = stream()["fantasy-land/map"](callback)

ArgumentumTípusKötelezőLeírás
callbackany -> anyIgenEgy callback, amelynek visszatérési értéke a stream értéke lesz.
visszatérStreamVisszaad egy streamet.

Hogyan kell olvasni a szignatúrákat

stream["fantasy-land/ap"] ​

Ennek a metódusnak a neve apply-t jelent. Ha egy a streamnek van egy függvénye értékként, akkor egy másik b stream használhatja azt a b.ap(a) argumentumaként. Az ap meghívása meghívja a függvényt a b stream értékével argumentumként, és egy másik streamet ad vissza, amelynek értéke a függvényhívás eredménye. Ez a metódus a Fantasy Land Applicative specifikációjának való megfelelés érdekében létezik. További információkért lásd a Mi az a Fantasy Land részt.

stream = stream()["fantasy-land/ap"](apply)

ArgumentumTípusKötelezőLeírás
applyStreamIgenEgy stream, amelynek értéke egy függvény.
visszatérStreamVisszaad egy streamet.

Alapvető használat ​

A streamek nem részei a Mithril.js alapvető terjesztésének. Ahhoz, hogy egy projektben használd őket, importáld a modult:

javascript
var stream = require('mithril/stream');

Streamek változókként ​

A stream() egy streamet ad vissza. A legalapvetőbb szinten egy stream hasonlóan működik, mint egy változó vagy egy getter-setter tulajdonság: állapotot tárolhat, amely módosítható.

javascript
var username = stream('John');
console.log(username()); // a konzolra kerül: "John"

username('John Doe');
console.log(username()); // a konzolra kerül: "John Doe"

A fő különbség az, hogy egy stream egy függvény, és ezért magasabb rendű függvényekbe komponálható.

javascript
var users = stream();

// felhasználók lekérése egy szerverről a fetch API használatával
fetch('/api/users')
  .then(function (response) {
    return response.json();
  })
  .then(users);

A fenti példában a users stream a válaszadatokkal van feltöltve, amikor a kérés teljesül.

Bidirekcionális kötések ​

A streamek esemény callbackekből és hasonlókból is feltölthetők.

javascript
// a stream
var user = stream('');

// egy kétirányú kötés a streamhez
m('input', {
  oninput: function (e) {
    user(e.target.value);
  },
  value: user(),
});

A fenti példában, amikor a felhasználó beírja az input mezőbe, a user stream frissül az input mezőjének értékére.

Számított tulajdonságok ​

A streamek hasznosak a számított tulajdonságok megvalósításához:

javascript
var title = stream('');
var slug = title.map(function (value) {
  return value.toLowerCase().replace(/\W/g, '-');
});

title('Hello world');
console.log(slug()); // a konzolra kerül: "hello-world"

A fenti példában a slug értéke akkor van kiszámítva, amikor a title frissül, nem pedig akkor, amikor a slug lekérdezésre kerül.

Természetesen az is lehetséges, hogy a tulajdonságokat több stream alapján számítsuk ki:

javascript
var firstName = stream('John');
var lastName = stream('Doe');
var fullName = stream.merge([firstName, lastName]).map(function (values) {
  return values.join(' ');
});

console.log(fullName()); // a konzolra kerül: "John Doe"

firstName('Mary');

console.log(fullName()); // a konzolra kerül: "Mary Doe"

A Mithril.js-ben a számított tulajdonságok atomikusan frissülnek: a több streamtől függő streamek soha nem lesznek többször meghívva értékfrissítésenként, függetlenül attól, hogy a számított tulajdonság függőségi gráfja mennyire összetett.

Streamek láncolása ​

A streamek a map metódussal láncolhatók. A láncolt stream más néven függő stream.

javascript
// szülő stream
var value = stream(1);

// függő stream
var doubled = value.map(function (value) {
  return value * 2;
});

console.log(doubled()); // a konzolra kerül: 2

A függő streamek reaktívak: az értékeik frissülnek, amikor a szülő streamje értéke frissül. Ez attól függetlenül történik, hogy a függő stream a szülő stream értékének beállítása előtt vagy után jött létre.

Megakadályozhatod a függő streamek frissítését, ha a stream.SKIP speciális értéket adod vissza.

javascript
var skipped = stream(1).map(function (value) {
  return stream.SKIP;
});

skipped.map(function () {
  // soha nem fut le
});

Streamek kombinálása ​

A streamek több szülő streamtől is függhetnek. Ezek a streamek a stream.merge() segítségével hozhatók létre.

javascript
var a = stream('hello');
var b = stream('world');

var greeting = stream.merge([a, b]).map(function (values) {
  return values.join(' ');
});

console.log(greeting()); // a konzolra kerül: "hello world"

Vagy használhatod a stream.lift() segédfüggvényt.

javascript
var a = stream('hello');
var b = stream('world');

var greeting = stream.lift(
  function (_a, _b) {
    return _a + ' ' + _b;
  },
  a,
  b
);

console.log(greeting()); // a konzolra kerül: "hello world"

A stream.combine() egy alacsonyabb szintű metódus, amely a reaktív számítások során közvetlen hozzáférést biztosít a streamekhez, ami komplexebb felhasználási módokat tesz lehetővé.

javascript
var a = stream(5);
var b = stream(7);

var added = stream.combine(
  function (a, b) {
    return a() + b();
  },
  [a, b]
);

console.log(added()); // a konzolra kerül: 12

Egy stream bármennyi streamtől függhet, és garantáltan atomikusan frissül. Például, ha egy A streamnek van két függő streamje, B és C, és egy negyedik D stream függ mind B-től, mind C-től, akkor a D stream csak egyszer frissül, ha az A értéke megváltozik. Ez garantálja, hogy a D stream callbackje soha nem lesz meghívva inkonzisztens értékekkel, például amikor B-nek van új értéke, de C-nek a régi értéke van. Az atomiság a teljesítmény előnyeit is magával hozza, mivel nem számolja újra a downstream-eket szükségtelenül.

Megakadályozhatod a függő streamek frissítését, ha a stream.SKIP speciális értéket adod vissza.

javascript
var skipped = stream.combine(
  function (stream) {
    return stream.SKIP;
  },
  [stream(1)]
);

skipped.map(function () {
  // soha nem fut le
});

Stream állapotok ​

Egy stream bármely adott időpontban a következő három állapot egyikében lehet: függőben, aktív vagy lezárt.

Függőben állapot ​

A függőben lévő streamek a stream() meghívásával hozhatók létre paraméterek nélkül.

javascript
var pending = stream();

Ha egy stream több streamtől függ, és bármelyik szülő streamje függőben van, akkor a függő stream is függőben van, és nem frissíti az értékét.

javascript
var a = stream(5);
var b = stream(); // függőben lévő stream

var added = stream.combine(
  function (a, b) {
    return a() + b();
  },
  [a, b]
);

console.log(added()); // a konzolra kerül: undefined

A fenti példában az added egy függőben lévő stream, mivel a b is függőben van.

Ez a stream.map segítségével létrehozott függő streamekre is vonatkozik:

javascript
var value = stream();
var doubled = value.map(function (value) {
  return value * 2;
});

console.log(doubled()); // a konzolra kerül: undefined, mert a `doubled` függőben van

Aktív állapot ​

Amikor egy stream értéket kap, aktívvá válik (hacsak a stream nincs lezárva).

javascript
var stream1 = stream('hello'); // stream1 aktív

var stream2 = stream(); // stream2 függőben indul
stream2('world'); // majd aktívvá válik

Egy több szülővel rendelkező függő stream akkor válik aktívvá, ha az összes szülője aktív.

javascript
var a = stream('hello');
var b = stream();

var greeting = stream.merge([a, b]).map(function (values) {
  return values.join(' ');
});

A fenti példában az a stream aktív, de a b függőben van. A b("world") beállítása azt eredményezné, hogy a b aktívvá válna, és ezért a greeting is aktívvá válna, és frissülne a "hello world" értékre.

Lezárt állapot ​

Egy stream leállíthatja a függő streamjeinek befolyásolását a stream().end(true) meghívásával. Ez hatékonyan eltávolítja a kapcsolatot egy stream és a függő streamjei között.

javascript
var value = stream();
var doubled = value.map(function (value) {
  return value * 2;
});

value.end(true); // lezárt állapotba állítva

value(5);

console.log(doubled());
// a konzolra kerül: undefined, mert a `doubled` már nem függ a `value`-tól

A lezárt streamek továbbra is rendelkeznek állapotkezelő szemantikával, azaz továbbra is használhatod őket getter-setterként, még a lezárásuk után is.

javascript
var value = stream(1);
value.end(true); // lezárt állapotba állítva

console.log(value(1)); // a konzolra kerül: 1

value(2);
console.log(value()); // a konzolra kerül: 2

Egy stream lezárása hasznos lehet olyan esetekben, amikor egy stream korlátozott élettartammal rendelkezik (például a mousemove eseményekre reagál csak addig, amíg egy DOM elem húzva van, de utána nem).

Streamek szerializálása ​

A streamek megvalósítják a .toJSON() metódust. Amikor egy stream argumentumként van átadva a JSON.stringify()-nak, a stream értéke szerializálva van.

javascript
var value = stream(123);
var serialized = JSON.stringify(value);
console.log(serialized); // a konzolra kerül: 123

A streamek nem indítják el a renderelést ​

A Knockout-hoz hasonló könyvtáraktól eltérően a Mithril.js streamek nem indítják el a sablonok újrarajzolását. Az újrarajzolás a Mithril.js komponens nézeteiben definiált eseménykezelőkre, útvonalváltozásokra vagy a m.request hívások feloldása után történik.

Ha az újrarajzolás más aszinkron eseményekre (pl. setTimeout/setInterval, websocket előfizetés, harmadik féltől származó könyvtár eseménykezelője stb.) válaszul kívánatos, akkor manuálisan kell meghívnod a m.redraw() függvényt.

Mi az a Fantasy Land ​

A Fantasy Land a közös algebrai struktúrák együttműködési képességét (interoperabilitását) specifikálja. Egyszerűen fogalmazva ez azt jelenti, hogy a Fantasy Land specifikációknak megfelelő könyvtárak felhasználhatók olyan általános funkcionális stílusú kód írására, amely a könyvtárak konstrukcióinak megvalósításától függetlenül működik.

Például tegyük fel, hogy létre akarunk hozni egy plusOne nevű általános függvényt. A naiv implementáció így nézne ki:

javascript
function plusOne(a) {
  return a + 1;
}

Ennek az implementációnak az a problémája, hogy csak számmal használható. Azonban lehetséges, hogy bármilyen logika is állítja elő az a értékét, az hibát is eredményezhet (egy Maybe-be vagy egy Either-be csomagolva egy olyan könyvtárból, mint a Sanctuary vagy a Ramda-Fantasy), vagy lehet egy Mithril.js stream, egy Flyd stream stb. Ideális esetben nem szeretnénk minden lehetséges típushoz külön verziót írni ugyanabból a függvényből, és nem szeretnénk ismétlődő csomagolási/kicsomagolási/hibakezelési kódot írni.

Itt segíthet a Fantasy Land. Írjuk át ezt a függvényt egy Fantasy Land algebra szempontjából:

javascript
var fl = require('fantasy-land');

function plusOne(a) {
  return a[fl.map](function (value) {
    return value + 1;
  });
}

Most ez a metódus bármely Fantasy Land kompatibilis Functor-ral működik, mint például a R.Maybe, a S.Either, a stream stb.

Ez a példa bonyolultnak tűnhet, de ez egy kompromisszum a bonyolultságban: a naiv plusOne implementáció akkor ésszerű, ha egyszerű rendszered van, és csak számokat növelsz, de a Fantasy Land implementáció erősebbé válik, ha nagy rendszered van sok csomagoló absztrakcióval és újrahasznosított algoritmussal.

Amikor eldöntöd, hogy be kell-e vezetned a Fantasy Land-et, figyelembe kell venned a csapatod funkcionális programozással kapcsolatos ismereteit, és reálisnak kell lenned a csapatod által a kódminőség fenntartására vállalt fegyelem szintjével kapcsolatban (szemben az új funkciók írásának és a határidők betartásának nyomásával). A funkcionális stílusú programozás nagymértékben függ a kis, pontosan definiált függvények nagy halmazának létrehozásától, karbantartásától és elsajátításától, ezért nem alkalmas olyan csapatok számára, amelyek nem rendelkeznek szilárd dokumentációs gyakorlatokkal, és/vagy hiányzik a tapasztalatuk a funkcionális orientált nyelvekben.

Pager
Előző oldalcensor(object, extra)
Következő oldalÚtmutató

A MIT licenc alapján kiadva.

Copyright (c) 2024 Mithril Contributors

https://mithril.js.org/stream.html

A MIT licenc alapján kiadva.

Copyright (c) 2024 Mithril Contributors