بازگشت به درس

دکوراتور معلق‌کننده

اهمیت: 5

نتیجه دکوراتور debounce(f, md) یک دربرگیرنده است که تا ms میلی‌ثانیه عدم فعالیت وجود نداشته باشد، فراخوانی‌های f را به حالت تعلیق در می‌آورد (فراخوانی انجام نمی‌شود، «مدت زمان آرام‌شدن») سپس f را با آخرین آرگومان‌ها فراخوانی می‌کند.

به عبارتی دیگر، debounce مانند یک منشی است که «تماس‌های تلفنی» را می‌پذیرد و تا زمانی که ms میلی‌ثانیه سکوت برقرار شود صبر می‌کند. و فقط بعد از این مدت اطلاعات آخرین تماس را به «رئیس» منتقل می‌کند (تابع واقعی f را فرا می‌خواند).

برای مثال، ما یک تابع f داشتیم و آن را با f = debounce(f, 1000) جایگزین کردیم.

سپس اگر تابع دربرگرفته شده در زمان‌های 0، 200، 500 میلی‌ثانیه فراخوانی شد، و پس از آن هیچ فراخوانی‌ای وجود نداشت، سپس تابع واقعی f فقط یک بار بعد از 1500 میلی‌ثانیه فراخوانی می‌شود. یعنی اینکه: پس از 1000 میلی‌ثانیه زمان آرام‌شدن از زمان آخرین فراخوانی.

…و این تابع آرگومان‌های آخرین فراخوانی را دریافت می‌کند و بقیه فراخوانی‌ها نادیده گرفته می‌شوند.

اینجا کدی برای آن داریم (از دکوراتور معلق‌کننده در کتابخانه Lodash library استفاده می‌کند):

let f = _.debounce(alert, 1000);

f("a");
setTimeout( () => f("b"), 200);
setTimeout( () => f("c"), 500);
// alert("c") :تابع معلق 1000 میلی‌ثانیه بعد از آخرین فراخوانی صبر می‌کند و سپس اجرا می‌شود

حالا یک مثال عملی. بیایید فرض کنیم که کاربر چیزی تایپ می‌کند و ما می‌خواهیم یک زمانی که وارد کردن تمام شد یک درخواست به سرور ارسال کنیم.

دلیلی برای فرستادن درخواست برای هر کاراکتر تایپ شده وجود ندارد. به جای آن ما می‌خواهیم صبر کنیم و سپس تمام نتیجه را پردازش کنیم.

در یک مرورگر وب، ما می‌توانیم یک کنترل‌کننده رویداد ترتیب دهیم – تابعی که برای هر تغییر در قسمت ورودی فراخوانی می‌شود. در حالت عادی، یک کنترل‌کننده رویداد خیلی فراخوانی می‌شود، برای هر کلید تایپ شده. اما اگر ما آن را به مدت 1000 میلی‌ثانیه debounce(معلق) کنیم، پس از 1000 میلی‌ثانیه بعد از آخرین ورودی، فقط یک بار فراخوانی می‌شود.

در این مثال زنده، کنترل‌کننده نتیجه را درون جعبه بیرون می‌گذارد، امتحانش کنید:

می‌بینید؟ ورودی دوم، تابع معلق را فراخوانی می‌کند پس محتوای آن پس از 1000 میلی‌ثانیه بعد از آخرین ورودی پردازش می‌شود.

پس debounce راهی عالی برای پردازش دنباله‌ای از رویدادها است: چه دنباله‎ای از فشار دادن کلیدها باشد، چه حرکت مَوس(mouse) یا هر چیز دیگری.

این تابع به اندازه زمان داده شده پس از آخرین فراخوانی صبر می‌کند و سپس تابع خودش که می‌تواند نتیجه را پردازش کند را فرا می‌خواند.

تمرین، پیاده‌سازی دکوراتور debounce است.

راهنمایی: اگر درباره آن فکر کنید، فقط چند خط می‌شود :)

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

function debounce(func, ms) {
  let timeout;
  return function() {
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(this, arguments), ms);
  };
}

فراخوانی debounce یک دربرگیرنده را برمی‌گرداند. زمانی که فرا خوانده شد، زمان‌بندی می‌کند که تابع اصلی بعد از مدت ms داده شده فراخوانی شود و زمان‌بندی قبلی را لغو می‌کند.

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