تقسیم کردن تکالیف طولانی

ویژگی‌های وب: Scheduler API

محاسبات سنگین یا حلقه‌های طولانی می‌توانند رشته اصلی را مسدود کنند و باعث شوند صفحه پاسخگو نباشد. برای جلوگیری از این اتفاق، باید به‌طور دوره‌ای کنترل را به مرورگر برگردانید. ‫scheduler.yield() API به شما امکان می‌دهد تکلیف طولانی را موقتاً متوقف کنید و به مرورگر اجازه دهید قبل‌از ادامه دادن، ورودی کاربر یا پردازش را مدیریت کند.

تقسیم کردن تکالیف طولانی

از scheduler.yield() در توابع ناهمگام برای تقسیم کار استفاده کنید.

async function processLargeArray(items) {
  // DO: Set a time-based deadline 50 milliseconds into the future. 50
  // milliseconds is the boundary for when a task becomes a long task.
  let deadline = performance.now() + 50; // 50ms budget

  for (const item of items) {
    // Process the item
    processItem(item);
    
    // MANDATORY: Yield to the main thread periodically to keep the UI
    // responsive. This can be done by checking if the deadline set earlier
    // has been exceeded. When it has been, yield, then reset the deadline
    // another 50 milliseconds into the future.
    if (performance.now() >= deadline) {
      await scheduler.yield();
      deadline = performance.now() + 50;
    }
  }
}

راهبردهای جایگزین

برخی‌از مرورگرها ممکن است از میانای برنامه‌سازی کاربردی scheduler پشتیبانی نکنند. برای اطمینان از اینکه کد بدون وقفه اجرا می‌شود، باید بااستفاده از setTimeout یک بازگشت پیاده‌سازی کنید.

گزینه جایگزین برای scheduler.yield()

async function processLargeArrayWithFallback(items) {
  // DO: Set a time-based deadline 50 milliseconds into the future.
  let deadline = performance.now() + 50;

  for (const item of items) {
    processItem(item);
    
    // MANDATORY: Yield to the main thread periodically to keep the UI responsive.
    if (performance.now() >= deadline) {
      // DO: Feature detect scheduler.yield
      if ('scheduler' in window && 'yield' in window.scheduler) {
        await scheduler.yield();
      } else {
        // DO: Fallback to setTimeout for older browsers
        await new Promise(resolve => setTimeout(resolve, 0));
      }
      deadline = performance.now() + 50;
    }
  }
}