decorator ritardante
Crea il decorator delay(f, ms)
che ritarda ogni chiamata ad f
di ms
millisecondi.
Ad esempio:
function f(x) {
alert(x);
}
// crea i wrappers
let f1000 = delay(f, 1000);
let f1500 = delay(f, 1500);
f1000("test"); // visualizza "test" dopo 1000ms
f1500("test"); // visualizza "test" dopo 1500ms
In altre parole, delay(f, ms)
ritorna una variante di f
ritardata di ms
.
Nel codice sopra, f
è una funzione con un solo argomento, ma la tua soluzione potrebbe passare molti argomenti ed il contesto this
.
La soluzione:
function delay(f, ms) {
return function() {
setTimeout(() => f.apply(this, arguments), ms);
};
}
let f1000 = delay(alert, 1000);
f1000("test"); // mostra "test" dopo 1000ms
Qui, nota come viene utilizzata un arrow function. come sappiamo le arrow functions non hanno un proprio this
nè arguments
, quindi f.apply(this, arguments)
prende this
e arguments
dal wrapper.
Se passassimo una funzione regolare, setTimeout
la chiamerebbe senza argomenti ethis = window
(supponendo essere in un browser).
Possiamo anche passare il this
corretto usando una variabile intermedia, ma è un po’ più complicato:
function delay(f, ms) {
return function(...args) {
let savedThis = this; // memorizzalo in una variabile intermedia
setTimeout(function() {
f.apply(savedThis, args); // usalo qui
}, ms);
};
}