Asynchron und einfädig JavaScript?
JavaScript ist eine Single-Thread-Sprache und gleichzeitig auch nicht-blockierend, asynchron und nebenläufig. Dieser Artikel wird Ihnen erklären, wie das geschieht.
Sehen Sie sich den dritten Teil unserer Artikelserie Power of functional programming in JavaScript an. Diesmal erklärt unser JavaScript-Experte mehr über Functor und Monad Maybe.
Oft ist es schwierig, Daten unveränderbar zu halten. Das Muster des Einpackens von Daten in einen Container bietet hier Abhilfe. Es sichert die Werte, so dass ihre Handhabung sicher ist und Nebenwirkungen ausgeschlossen werden.
Wenn Sie neu hier sind, schauen Sie sich unbedingt meine letzten 2 Teile über funktionale Programmierung auf dem The Codest Blog an:
Sie hat keine komplexe Logik. Seine Hauptaufgabe besteht darin, den Kontext zu verpacken und die Funktionen, die er von außen erhält, mit ihm durchzuführen. Jedes Mal, wenn sich der Wert ändert, wird eine neue Container-Instanz neu verpackt und zurückgegeben. Beim Aufruf der Karte Methode, die eine bestimmte Aktion ausführt, gibt sie eine neue Containerinstanz mit dem von der übergebenen Funktion zurückgegebenen Wert zurück, wobei der Grundsatz der Nichtveränderbarkeit beibehalten wird.
const Functor = value => ({
map: fn => Functor(fn(value)),
chain: fn => fn(value),
of: () => value
});
Karte - nützlich, wenn Sie den Zustand eines Wertes in einem Container ändern, ihn aber noch nicht zurückgeben wollen.
Kette - wird verwendet, wenn Sie einen Wert an eine Funktion übergeben wollen, ohne den Zustand des Containers zu verändern. Normalerweise am Ende von Karte Anrufe.
von - Rückgabe des aktuellen Wertes
const randomInt = (max) => Math.floor(Math.random() * (max + 1))
const randomNumber = randomInt(200) // liefert eine Zahl zwischen 0 und 200
decrease(randomNumber) // gibt (Zahl zwischen 0 und 200) - 1 zurück
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() // liefert eine Zahl zwischen 0 und 200
randomNumber.chain(decrease) // gibt (Zahl zwischen 0 und 200) - 1 zurück
Manchmal benötigt man zusätzlich zu den Funktionen, die den neuen Zustand des Wertes auslösen, zusätzliche Logik, die im Container versteckt ist. Hier kommt die Monade ins Spiel, denn sie ist eine Erweiterung von Funktor. Sie kann z. B. entscheiden, was geschehen soll, wenn der Wert einen bestimmten Wert hat, oder welchen Weg die nächsten Aktionen nehmen sollen.
Monad löst vielleicht das Problem von Werten, die nicht true zurückgeben. Wenn dies geschieht, werden nachfolgende Karte Aufrufe werden ignoriert, aber es erlaubt Ihnen, eine Alternative zurückzugeben, indem Sie die getOr Methode. Damit können Sie die Verwendung von if / else-Operatoren vermeiden, die in Imperativ Programmierung. Diese Monade besteht aus drei Containern:
Nichts - wird ausgeführt, wenn ein Wert, der nicht wahr ist, in den Container fällt oder Filter Methode gibt false zurück. Sie wird verwendet, um die Ausführung einer Funktion zu simulieren. Das bedeutet, dass dieser Container die Funktion empfängt, sie aber nicht ausführt.
Einfach - Dies ist der Hauptcontainer, der alle Funktionen ausführt, aber wenn sich der Wert zu einem falschen Wert ändert oder Filter Methode false zurückgibt, wird sie an die Methode Nichts Container.
Vielleicht - Ich nehme den Ausgangswert und entscheide, welchen Container ich zu Beginn aufrufe.
const Just = value => ({
map: fn => Maybe(fn(Wert)),
chain: fn => fn(Wert),
of: () => value,
getOr: () => Wert,
filter: fn => fn(Wert) ? Just(value) : Nothing(),
type: 'just'
});
const Nothing = () => ({
map: fn => Nothing(),
chain: fn => fn(),
of: () => Nothing(),
getOr: substitute => substitute,
filter: () => Nothing(),
type: 'nichts'
});
const Maybe = Wert =>
wert === null || wert === undefiniert || wert.typ === 'nichts'
? Nothing()
: Just(Wert)
Lassen Sie uns nun das vorherige Beispiel über die Bedingung aufbauen. Wenn max größer als Null ist, wird die Funktion ausgeführt. Andernfalls wird sie 0 zurückgeben.
const randomInt = (max) => {
if(max > 0) {
return Math.floor(Math.random() * (max + 1))
} else {
return 0
}
}
const bookMiddlePage = 200
const randomPage = randomInt(10) || bookMiddlePage // liefert zufällig
const randomPage = randomInt(-10) || bookMiddlePage // gibt 200 zurück
const randomIntWrapper = (max) =>
Maybe(max)
.filter(max => max > 0) // Wert false ignoriert weitere Aufrufe
.map(increase)
.map(multiplyBy(Math.random()))
.map(Math.floor)
const bookMiddlePage = 200
// Nur Container
const randomPage = randomIntWrapper(10).getOr(bookMiddlePage) // liefert zufällig
// Nichts-Container
const randomPage = randomIntWrapper(-10).getOr(bookMiddlePage) // gibt 200 zurück