Asynchronní a jednovláknový JavaScript?
JavaScript je jednovláknový jazyk a zároveň neblokující, asynchronní a souběžný. Tento článek vám vysvětlí, jak se to děje.
Podívejte se na třetí díl našeho seriálu článků Power of functional programming in JavaScript. Tentokrát náš odborník na JavaScript vysvětluje více o funktoru a monádě Maybe.
Často je obtížné udržovat nemodifikovatelnost. Na pomoc přichází vzor zabalení dat do kontejneru. Zabezpečuje hodnoty tak, aby manipulace s nimi byla bezpečná s vyloučením vedlejších účinků.
Pokud jste zde noví, určitě se podívejte na mé poslední dva díly týkající se funkčního programování na blogu The Codest:
Nemá žádnou složitou logiku. Jeho hlavním úkolem je obalit kontext a provádět na něm funkce, které obdrží zvenčí. Při každé změně hodnoty je přebalena a vrácena nová instance kontejneru. Při volání mapa která provádí určitou akci, vrací novou instanci kontejneru s hodnotou vrácenou předanou funkcí, přičemž je zachován princip nemodifikovatelnosti.
const Functor = value => ({ {
map: fn => Functor(fn(value)),
chain: fn => fn(value),
of: () => value
});
mapa - užitečné, když chcete změnit stav hodnoty v kontejneru, ale ještě ji nechcete vrátit.
řetěz - se používá, pokud chcete funkci předat hodnotu, aniž byste změnili stav kontejneru. Obvykle na konci mapa telefonáty.
z - vrátit aktuální hodnotu
const randomInt = (max) => Math.floor(Math.random() * (max + 1))
const randomNumber = randomInt(200) // vrací číslo mezi 0 a 200
decrease(randomNumber) // vrací (číslo mezi 0 a 200) - 1
const randomIntWrapper = (max) =>
Functor(max)
.map(increase) // max + 1
.map(multiplyBy(Math.random())) // Math.random() * (max + 1)
.map(Math.floor) // Math.floor(Math.random() * (max + 1))
const randomNumber = randomIntWrapper(200)
randomNumber.of() // vrací číslo mezi 0 a 200
randomNumber.chain(decrease) // vrací (číslo mezi 0 a 200) - 1
Někdy je kromě funkcí, které spouštějí nový stav hodnoty, potřeba další logika skrytá v kontejneru. V tomto případě se hodí monáda, která je rozšířením funkce funktor. Může například rozhodnout, co se má stát, když hodnota nabývá určité hodnoty, nebo jakou cestou se mají ubírat další akce.
Monády možná řeší problém hodnot, které nevracejí true. Když se to stane, následné mapa je ignorováno, ale umožňuje vrátit alternativu voláním příkazu getOr metoda. Umožňuje vyhnout se použití operátorů if / else, které jsou oblíbené v metodách typu imperativ programování. Tato monáda se skládá ze tří kontejnerů:
Nic - se spustí, když do kontejneru spadne hodnota, která není true nebo filtr metoda vrací false. Používá se k simulaci provádění funkce. To znamená, že tento kontejner přijme funkci, ale neprovede ji.
Jen - je to hlavní kontejner, který vykonává všechny funkce, ale pokud se hodnota změní na hodnotu false nebo filtr se vrátí false, předá ji metodě Nic kontejner.
Možná - Vezmu počáteční hodnotu a rozhodnu se, jaký kontejner zavolat na začátku.
const Just = value => ({
map: fn => Maybe(fn(value)),
chain: fn => fn(value),
of: () => value,
getOr: () => value,
filter: fn => fn(value) ? Just(value) : Nic(),
type: 'just'
});
const Nothing = () => ({
map: fn => Nothing(),
chain: fn => fn(),
of: () => Nothing(),
getOr: substitute => substitute,
filter: () => Nothing(),
type: "nothing
});
const Maybe = value =>
value === null || value === undefined || value.type === 'nothing'
? nic()
: Just(value)

Nyní navážeme na předchozí příklad o podmínce. Pokud je max větší než nula, funkce se provede. V opačném případě vrátí 0.
const randomInt = (max) => {
if(max > 0) {
return Math.floor(Math.random() * (max + 1))
} else {
return 0
}
}
const bookMiddlePage = 200
const randomPage = randomInt(10) || bookMiddlePage // vrací náhodnou hodnotu
const randomPage = randomInt(-10) || bookMiddlePage // vrací 200
const randomIntWrapper = (max) =>
Maybe(max)
.filter(max => max > 0) // hodnota false ignoruje další volání
.map(increase)
.map(multiplyBy(Math.random()))
.map(Math.floor)
const bookMiddlePage = 200
// Jen kontejner
const randomPage = randomIntWrapper(10).getOr(bookMiddlePage) // vrací náhodný údaj
// Nic kontejneru
const randomPage = randomIntWrapper(-10).getOr(bookMiddlePage) // vrací 200