Asincrono e a thread singolo JavaScript?
JavaScript è un linguaggio a thread singolo e, allo stesso tempo, non bloccante, asincrono e concorrente. Questo articolo vi spiegherà come avviene.
Ecco la terza parte della nostra serie di articoli sul potere della programmazione funzionale in JavaScript. Questa volta il nostro esperto JavaScript ci spiega di più su Functor e Monad Maybe.
Spesso mantenere l'immodificabilità è difficile da mantenere. Il modello di avvolgimento dei dati in un contenitore viene in soccorso. Esso protegge i valori in modo che la loro manipolazione sia sicura, con l'esclusione di effetti collaterali.
Se siete nuovi qui, assicuratevi di controllare le mie ultime due parti sulla programmazione funzionale sul blog The Codest:
Non ha una logica complessa. Il suo compito principale è avvolgere il contesto ed eseguire su di esso le funzioni che riceve dall'esterno. Ogni volta che il valore cambia, una nuova istanza del contenitore viene reimpacchettata e restituita. Quando si chiama il metodo mappa che esegue un'azione specifica, restituisce una nuova istanza del contenitore con il valore restituito dalla funzione passata, mantenendo il principio di non modificabilità.
const Functor = value => ({
map: fn => Functor(fn(valore)),
catena: fn => fn(valore),
di: () => valore
});
mappa - utile quando si vuole cambiare lo stato di un valore in un contenitore, ma non si vuole ancora restituirlo.
catena - utilizzato se si vuole passare un valore a una funzione senza modificare lo stato del contenitore. Di solito alla fine di mappa chiamate.
di - restituire il valore corrente
const randomInt = (max) => Math.floor(Math.random() * (max + 1))
const randomNumber = randomInt(200) // restituisce un numero compreso tra 0 e 200
decrease(randomNumber) // restituisce (numero tra 0 e 200) - 1
const randomIntWrapper = (max) =>
Funtore(max)
.map(increase) // max + 1
.map(multiplyBy(Math.random()) // Math.random() * (max + 1)
.map(Math.floor) // Math.floor(Math.random() * (max + 1))
const NumeroCasuale = randomIntWrapper(200)
randomNumber.of() // restituisce un numero compreso tra 0 e 200
randomNumber.chain(decrease) // restituisce (numero tra 0 e 200) - 1
A volte, oltre alle funzioni che attivano il nuovo stato del valore, è necessaria una logica aggiuntiva nascosta nel contenitore. È qui che torna utile la monade, che è un'estensione di funtore. Può, ad esempio, decidere cosa deve accadere quando il valore ha un determinato valore o quale percorso devono seguire le azioni successive.
La monade forse risolve il problema dei valori che non ritornano veri. Quando ciò accade, i successivi mappa sono ignorate, ma permette di restituire un'alternativa chiamando il metodo getOr metodo. Consente di evitare l'uso degli operatori if / else, molto diffusi in imperativo programmazione. Questa monade è composta da tre contenitori:
Nulla - viene eseguito quando un valore che non è vero cade nel contenitore o nel contenitore filtro restituisce false. Viene utilizzato per simulare l'esecuzione di una funzione. Ciò significa che questo contenitore riceve la funzione, ma non la esegue.
Solo - questo è il contenitore principale che esegue tutte le funzioni, ma se il valore cambia in un valore falso o in un valore filtro restituisce false, lo passerà al metodo Nulla contenitore.
Forse - Prendo il valore iniziale e decido quale contenitore chiamare all'inizio.
const Just = valore => ({
map: fn => Maybe(fn(valore)),
catena: fn => fn(valore),
di: () => valore,
getOr: () => valore,
filter: fn => fn(valore) ? Just(valore) : Nothing(),
tipo: 'just'
});
const Nothing = () => ({
map: fn => Nothing(),
chain: fn => fn(),
di: () => Nothing(),
getOr: substitute => substitute,
filter: () => Nothing(),
tipo: 'nothing'
});
const Maybe = valore =>
value === null || value === undefined || value.type === 'nothing'
? Nothing()
: Just(valore)
Ora costruiamo l'esempio precedente sulla condizione. Se max è maggiore di zero, la funzione verrà eseguita. In caso contrario, restituirà 0.
const randomInt = (max) => {
if(max > 0) {
return Math.floor(Math.random() * (max + 1))
} else {
restituisce 0
}
}
const bookMiddlePage = 200
const randomPage = randomInt(10) || bookMiddlePage // restituisce random
const randomPage = randomInt(-10) || bookMiddlePage // restituisce 200
const randomIntWrapper = (max) =>
Forse(max)
.filter(max => max > 0) // il valore false ignora le ulteriori chiamate
.map(incremento)
.map(multiplyBy(Math.random())
.map(Math.floor)
const bookMiddlePage = 200
// Solo un contenitore
const randomPage = randomIntWrapper(10).getOr(bookMiddlePage) // restituisce random
// Nulla contenitore
const randomPage = randomIntWrapper(-10).getOr(bookMiddlePage) // restituisce 200