tilbage til lektionen

Forsinkelses decorator

vigtighed: 5

Opret en decorator delay(f, ms) der forsinker hvert kald af f med ms millisekunder.

For eksempel:

function f(x) {
  alert(x);
}

// Opret wrappers der forsinker kaldet af f med 1000ms og 1500ms
let f1000 = delay(f, 1000);
let f1500 = delay(f, 1500);

f1000("test"); // viser "test" efter 1000ms
f1500("test"); // viser "test" efter 1500ms

Med andre ord: delay(f, ms) returner en udgave af f der er “forsinket med ms millisekunder”.

I koden ovenfor er f en funktion med et enkelt argument, men din løsning skal videregive alle argumenter og konteksten this.

Åbn en sandbox med tests.

Løsningen:

function delay(f, ms) {

  return function() {
    setTimeout(() => f.apply(this, arguments), ms);
  };

}

let f1000 = delay(alert, 1000);

f1000("test"); // viser "test" efter 1000ms

Bemærk hvordan en arrow function er brugt her. Som vi ved, har arrow functions ingen egen this og arguments, så f.apply(this, arguments) tager this og arguments fra wrapperen.

Hvis vi sender en almindelig funktion, vil setTimeout kalde den uden argumenter og med this=window (hvis vi er i browseren).

Vi kan stadig videregive det rigtige this ved at bruge en midlertidig variabel, men det er lidt mere besværligt:

function delay(f, ms) {

  return function(...args) {
    let savedThis = this; // gem this som en midlertidig variabel
    setTimeout(function() {
      f.apply(savedThis, args); // brug den her
    }, ms);
  };

}

Åbn løsningen med tests i en sandbox.