Asynkron og enkelttrådet JavaScript?
JavaScript er et single-threaded sprog og samtidig også ikke-blokerende, asynkront og concurrent. Denne artikel vil forklare dig, hvordan det sker.
Se tredje del af vores artikelserie Power of functional programming in JavaScript. Denne gang forklarer vores JavaScript-ekspert mere om Functor og Monad Maybe.
Ofte er det svært at vedligeholde noget, der ikke kan ændres. Mønsteret med at pakke data ind i en container kommer til undsætning. Det sikrer værdierne, så det er sikkert at håndtere dem uden bivirkninger.
Hvis du er ny her, skal du sørge for at tjekke mine sidste to dele om funktionel programmering på The Codest-bloggen om:
Den har ingen kompleks logik. Dens hovedopgave er at pakke konteksten ind og udføre de funktioner, den modtager udefra, på dem. Hver gang værdien ændres, pakkes en ny containerinstans ind igen og returneres. Når man kalder kort metode, som kræver en bestemt handling, returnerer den en ny containerinstans med den værdi, der returneres af den afleverede funktion, samtidig med at princippet om, at den ikke kan ændres, opretholdes.
const Functor = value => ({
map: fn => Functor(fn(value)),
chain: fn => fn(value),
of: () => value
});
kort - nyttig, når du vil ændre tilstanden for en værdi i en container, men ikke vil returnere den endnu.
kæde - bruges, hvis man vil sende en værdi til en funktion uden at ændre containerens tilstand. Normalt i slutningen af kort opkald.
af - Returner den aktuelle værdi
const randomInt = (max) => Math.floor(Math.random() * (max + 1))
const randomNumber = randomInt(200) // returnerer tal mellem 0 og 200
decrease(randomNumber) // returnerer (tal mellem 0 og 200) - 1
const tilfældigIntWrapper = (max) => (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() // returnerer tal mellem 0 og 200
randomNumber.chain(decrease) // returnerer (tal mellem 0 og 200) - 1
Ud over de funktioner, der udløser den nye tilstand af værdien, har du nogle gange brug for yderligere logik skjult i containeren. Det er her, monad er praktisk, da det er en udvidelse af Funktor. Den kan f.eks. beslutte, hvad der skal ske, når værdien har en bestemt værdi, eller hvilken vej de næste handlinger skal gå.
Monad maybe løser problemet med værdier, der ikke returnerer true. Når dette sker, vil efterfølgende kort ignoreres, men det giver dig mulighed for at returnere et alternativ ved at kalde getOr metode. Det giver dig mulighed for at undgå brugen af if/ else-operatorer, som er populære i tvingende nødvendigt programmering. Denne monade består af tre containere:
Ingenting - kører, når en værdi, der ikke er sand, falder ind i beholderen eller filter metoden returnerer falsk. Den bruges til at simulere udførelsen af en funktion. Det betyder, at denne container modtager funktionen, men ikke udfører den.
Bare - dette er hovedbeholderen, der udfører alle funktionerne, men hvis værdien ændres til en falsk værdi eller filter metoden returnerer false, vil den sende den videre til Ingenting container.
Måske - Jeg tager startværdien og beslutter, hvilken container der skal kaldes i starten.
const Just = værdi => ({
map: fn => Maybe(fn(value)),
chain: fn => fn(value),
of: () => value,
getOr: () => value,
filter: fn => fn(værdi) ? Just(værdi) : Intet(),
type: 'bare'
});
const Nothing = () => ({
map: fn => Nothing(),
chain: fn => fn(),
of: () => Nothing(),
getOr: substitute => substitute,
filter: () => Nothing(),
type: 'intet'
});
const Maybe = værdi =>
value === null || value === undefined || value.type === 'nothing'
? Intet()
: Just(værdi)
Lad os nu bygge det tidligere eksempel om betingelsen. Hvis max er større end nul, vil funktionen blive udført. Ellers vil den returnere 0.
const randomInt = (max) => {
if(max > 0) {
return Math.floor(Math.random() * (max + 1))
} ellers {
returnerer 0
}
}
const bookMiddlePage = 200
const randomPage = randomInt(10) || bookMiddlePage // returnerer tilfældigt
const randomPage = randomInt(-10) || bookMiddlePage // returnerer 200
const randomIntWrapper = (max) => (max)
Måske(max)
.filter(max => max > 0) // værdien false ignorerer yderligere kald
.map(forøgelse)
.map(multiplyBy(Math.random()))
.map(Math.floor)
const bookMiddlePage = 200
// Bare container
const randomPage = randomIntWrapper(10).getOr(bookMiddlePage) // returnerer tilfældigt
// Intet beholder
const randomPage = randomIntWrapper(-10).getOr(bookMiddlePage) // returnerer 200