تقسيم المهام الطويلة

ميزات الويب: Scheduler API

يمكن أن تؤدي العمليات الحسابية الثقيلة أو التكرارات الطويلة إلى حظر سلسلة التعليمات الرئيسية، ما يؤدي إلى عدم استجابة الصفحة. لتجنّب ذلك، عليك إعادة التحكّم إلى المتصفّح بشكل دوري. تتيح لك واجهة برمجة التطبيقات scheduler.yield() إيقاف مهمة يستغرق تنفيذها وقتًا طويلاً مؤقتًا والسماح للمتصفّح بمعالجة بيانات أدخلها المستخدم أو العرض قبل المتابعة.

تقسيم المهام الطويلة

استخدِم 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;
    }
  }
}