kembali ke pelajaran

Dekorator penunda

Buatlah sebuah dekorator delay(f, ms) yang menunda setiap pemanggilan dari f selama ms milidetik.

Contoh:

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

// create wrappers
let f1000 = delay(f, 1000);
let f1500 = delay(f, 1500);

f1000("test"); // tampilkan "test" setelah 1000ms
f1500("test"); // tampilkan "test" setelah 1500ms

Dengan kata lain, delay(f, ms) mengembalikan sebuah "varian dari f yang telah ditunda selama ms".

Didalam kode diatas, f adalah sebuah fungsi dari sebuah argumen tunggal, tapi solusimu harus bisa melewati seluruh argumen dan konteks dari this.

Buka sandbox dengan tes.

Solusi:

function delay(f, ms) {

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

}

let f1000 = delay(alert, 1000);

f1000("test"); // tampilkan "test" setelah 1000ms

Perhatikan bagaimana fungsi arrow digunakan disini. Seperti yang kita tahu, fungsi panah tidak memiliki this dan argumennya sendiri, jadi f.apply(this, arguments) akan mengambil this dan arguments dari pembungkusnya.

Jika kita memasukan fungsi yang biasa, setTimeout akan memanggil fungsinya tanpa argumen dan this=window (asumsikan kita berada didalam peramban).

Kita masih bisa memberikan this yang benar dengan menggunakan variabel tambahan, tapi kodenya akan sedikit menjadi lebih rumit:

function delay(f, ms) {

  return function(...args) {
    let savedThis = this; // simpan this kedalam variabel tambahan
    setTimeout(function() {
      f.apply(savedThis, args); // gunakan disini
    }, ms);
  };

}

Buka solusi dengan tes di sandbox.