في Scheduler.js ،
function unstable_shouldYield() {
return (
!currentDidTimeout &&
((firstCallbackNode !== null &&
firstCallbackNode.expirationTime < currentExpirationTime) ||
shouldYieldToHost())
);
}
unstable_shouldYield () يعود صحيحًا عندما تكون currentDidTimeout خاطئة ويجب أن تعود ()ieldToHost () على صواب ، ولكن لماذا؟
shouldYieldToHost = function() {
return frameDeadline <= getCurrentTime();
};
shouldYieldToHost () إرجاع صحيح يعني أنه لم يتبق وقت في فترة الخمول هذه
currentDidTimeout خاطئ يعني أن الجدول الزمني ليس مهلة
ما العلاقة بينهما ، لماذا تعتمد () unstable_shouldYield () عليهم؟
نعطي البيئة المضيفة بشكل دوري - كل 16 مللي ثانية أو نحو ذلك - للسماح للتصفح بمعالجة الأحداث الواردة بما في ذلك مدخلات المستخدم. frameDeadline
هو الطابع الزمني الذي نخطط للإنتاج عليه (تم تعيينه في الأصل على شيء مثل now() + 16ms
) ، لذا يجب أن تعود القيمة true بمجرد مرور ذلك الوقت. ثم نستخدم مزيجًا من requestIdleCallback و requestAnimationFrame حتى نتمكن من معالجة الجزء التالي من العمل قريبًا.
في الحالة المثالية ، يمكننا إنهاء كل العرض في شرائح 16 مللي ثانية الصغيرة. ومع ذلك ، إذا كان هناك العديد من الأشياء الأخرى التي تحدث في نفس الوقت ، فقد "يجوع" عمل React ولن يكون قادرًا على تقديمه بشكل كامل في الشرائح الصغيرة. لذلك لدينا فحص ثانٍ: كل تصيير معلق أو تحديث حالة له "وقت انتهاء صلاحية" (عادةً في مكان ما من 100 مللي ثانية إلى 5000 مللي ثانية) - إذا مر هذا الوقت دون إنهاء التجسيد ، فإننا ننتقل إلى الوضع المتزامن حتى يمكن الانتهاء من هذا التحديث. هذا ليس مثاليًا ولكنه يضمن معالجة جميع التحديثات دون الانتظار لفترة طويلة.
قمنا بتعيين مؤقت في المتصفح (على سبيل المثال ، مع setTimeout) لنفس وقت انتهاء الصلاحية. إذا انطلق هذا المؤقت ، فنحن نعلم أننا بحاجة إلى أداء العمل بشكل متزامن. إذا حدث هذا ، فسيتم تعيين currentDidTimeout
على true ، لذلك لن نتحقق.
في المستقبل ، نخطط لاستخدام واجهة برمجة تطبيقات جديدة لمتصفح isInputPending
(https://github.com/WICG/is-input-pending) حتى نتمكن من متابعة العمل وتحقيق العائد فقط عندما يكون هناك إدخال مستخدم جديد ، بدلاً من الاستغناء دائمًا عن كل 16 مللي ثانية.
شكرا على الرد
لا يزال لدي بعض الأسئلة ،
unstable_shouldYield()
يمثل ما إذا كان يمكن مقاطعة العمل أم لا في الجدول ، فهل هذا صحيح؟activeFrameTime
؟firstCallbackNode.expirationTime < currentExpirationTime
صحيحًا؟ هل هذا يعني أن أولوية العمل التالي أعلى من سابقتها؟يجب أن تقوم كل مهمة عرض بالتحقق من unstable_shouldYield () بشكل متكرر. (نسميها تقريبًا بعد كل مكون في الشجرة.) في معظم الأحيان ، ستُرجع القيمة false (مما يعني الاستمرار) ولكن عندما تعود صحيحة ، فهذا يعني أن العرض يحتاج إلى التوقف مؤقتًا.
نعم.
أعتقد أن هذا الشرط صحيح إذا تم إدراج بعض الأعمال الجديدة ذات الأولوية العالية في قائمة الانتظار أثناء تصيير موجود. في هذه الحالة ، نريد العودة صحيحًا حتى نتمكن من التبديل إلى هذه المهمة.
شكرا جزيلا لك انه لطف منك حقا!
التعليق الأكثر فائدة
نعطي البيئة المضيفة بشكل دوري - كل 16 مللي ثانية أو نحو ذلك - للسماح للتصفح بمعالجة الأحداث الواردة بما في ذلك مدخلات المستخدم.
frameDeadline
هو الطابع الزمني الذي نخطط للإنتاج عليه (تم تعيينه في الأصل على شيء مثلnow() + 16ms
) ، لذا يجب أن تعود القيمة true بمجرد مرور ذلك الوقت. ثم نستخدم مزيجًا من requestIdleCallback و requestAnimationFrame حتى نتمكن من معالجة الجزء التالي من العمل قريبًا.في الحالة المثالية ، يمكننا إنهاء كل العرض في شرائح 16 مللي ثانية الصغيرة. ومع ذلك ، إذا كان هناك العديد من الأشياء الأخرى التي تحدث في نفس الوقت ، فقد "يجوع" عمل React ولن يكون قادرًا على تقديمه بشكل كامل في الشرائح الصغيرة. لذلك لدينا فحص ثانٍ: كل تصيير معلق أو تحديث حالة له "وقت انتهاء صلاحية" (عادةً في مكان ما من 100 مللي ثانية إلى 5000 مللي ثانية) - إذا مر هذا الوقت دون إنهاء التجسيد ، فإننا ننتقل إلى الوضع المتزامن حتى يمكن الانتهاء من هذا التحديث. هذا ليس مثاليًا ولكنه يضمن معالجة جميع التحديثات دون الانتظار لفترة طويلة.
قمنا بتعيين مؤقت في المتصفح (على سبيل المثال ، مع setTimeout) لنفس وقت انتهاء الصلاحية. إذا انطلق هذا المؤقت ، فنحن نعلم أننا بحاجة إلى أداء العمل بشكل متزامن. إذا حدث هذا ، فسيتم تعيين
currentDidTimeout
على true ، لذلك لن نتحقق.في المستقبل ، نخطط لاستخدام واجهة برمجة تطبيقات جديدة لمتصفح
isInputPending
(https://github.com/WICG/is-input-pending) حتى نتمكن من متابعة العمل وتحقيق العائد فقط عندما يكون هناك إدخال مستخدم جديد ، بدلاً من الاستغناء دائمًا عن كل 16 مللي ثانية.