بازگشت به درس

دکوراتور تأخیر انداز

اهمیت: 5

یک دکوراتور delay(f, ms) بسازید که هر فراخوانی f را به اندازه ms میلی‌ثانیه به تأخیر می‌اندازد.

برای مثال:

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

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

f1000("test"); // را بعد از 1000 میلی‌ثانیه نشان می‌دهد "test"
f1500("test"); // را بعد از 1500 میلی‌ثانیه نشان می‌دهد "test"

به عبارتی دیگر، delay(f, ms) یک نوع از f که «به اندازه ms تأخیر دارد» را برمی‌گرداند.

در کد بالا، f تایعی است که یک آرگومان دارد اما راه‌حل شما باید تمام آرگومان‌ها و زمینه this را در فراخوانی قرار دهد.

باز کردن یک sandbox همراه با تست‌ها.

راه‌حل:

function delay(f, ms) {

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

}

لطفا به چگونگی استفاده از تابع کمانی در اینجا توجه کنید. همانطور که می‌دانیم، تابع‌های کمانی this و arguments خودشان را ندارند پس f.apply(this, arguments) مقدار this و arguments را از دربرگیرنده می‌گیرند.

اگر ما یک تابع معمولی را قرار دهیم، setTimeout آن را بدون آرگومان‌ها و this=window (در مرورگر) فراخوانی خواهد کرد، پس ما باید کمی بیشتر کد بنویسیم تا آن‌ها از طریق دربرگیرنده رد و بدل کنیم:

function delay(f, ms) {

  // قرار دهیم setTimeout و آرگومان‌ها را از طریق دربرگیرنده درون this متغیرهایی اضافه کردیم تا
  return function(...args) {
    let savedThis = this;
    setTimeout(function() {
      f.apply(savedThis, args);
    }, ms);
  };

}
function delay(f, ms) {

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

};

باز کردن راه‌حل همراه با تست‌ها درون یک sandbox.