هل يمكننا اعتبار requestAnimFrame بمثابة "عائد" في حلقة التطبيق للسماح بمعالجة حلقة الحدث؟

StackOverflow https://stackoverflow.com//questions/21010396

سؤال

أنا أستخدم requestAnimFrame طريقة في JavaScript لإجراء تحديث اللوحة القماشية الخاصة بي ضمن الحلقة الرئيسية لبرنامجي:

window.requestAnimFrame = (function(callback) {
  return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
    function(callback) {
      window.setTimeout(callback, 1000 / 60);
    };
})();


function animate() {
    requestAnimationFrame( animate );
//var runcount = 100;
//for (var i=0;i<=100;i++) {
    draw();
//    if (runcount === i)
//        alert("Completed program loop");
//    }
}

ما كان يحدث هو ذلك برنامجي الذي قام بتحديث اللوحة القماشية فقط بعد تشغيل الحلقة الرئيسية الخاصة بي لمدة 100 التكرار ثم توقف.بعد أن أقوم بإضافة الطريقة المذكورة أعلاه في حلقتي الرئيسية، وفجأة أحصل على تحديثات اللوحة القماشية في كل حلقة من برنامجي.

حقيقة أن اللوحة القماشية لم يتم تحديثها حتى انتهاء برنامجي جعلتني أعتقد أن تحديث اللوحة القماشية كان يعمل في موضوع مختلف لم يحظى بالأولوية.(لكننا نعرف ذلك جافا سكريبت هي خيط واحد).

سؤالي هو - هل يمكننا اعتبار requestAnimFrame بمثابة "عائد" في حلقة التطبيق للسماح بمعالجة حلقة الحدث؟ هل ما زال بإمكاني افتراض أن JavaScript عبارة عن خيط واحد؟

هل كانت مفيدة؟

المحلول

أنت لست محددًا بشأن كيفية قيامك بالتكرار 1000 مرة، لكنني سأفترض أنك تقصد أنك قمت بالتكرار باستخدام for أو while حلقة (؟وصححوني إن كنت مخطئا..).

عندما تقوم بحلقة for/while، سيكون البرنامج النصي مشغولاً بالتكرار حتى تكتمل تلك الحلقة (أو النطاق).نظرًا لأن JS كما تعلم أحادي الترابط، فإنه لا يمكنه معالجة أشياء مثل قائمة انتظار الأحداث أثناء قيامه بذلك - وبالتالي لن يتمكن أي شيء من التحديث (بما في ذلك.DOM) حتى تنتهي الحلقة (بشكل عام، قد يكون هناك تطبيق خاص بالمتصفح يسمح بتحديثات DOM إذا تم تشغيل تحديثات DOM في سلسلة منفصلة على سبيل المثال ولكن هذا شيء منفصل عن JS).

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

كان من الممكن أن تستخدم setTimeout أيضًا.ما يفعله سلاح الجو الملكي البريطاني بشكل مختلف عن على سبيل المثال setTimeout أو setInterval هو أنه تطبيق فعال على مستوى منخفض لآلية توقيت قادرة على المزامنة مع جهاز العرض VBLANK الفترة (التقطيع العمودي الذي تخضع له بطاقة الفيديو من خلال خيار يسمى vsync) - وهذا يعني بكلمة واضحة معدل تحديث الشاشة (عادةً 60 هرتز).يتيح لنا هذا إنشاء رسوم متحركة سلسة ولهذا السبب يطلق عليها اسم request*Animation*Frame لأن هذا هو ما تم تصميمه من أجله في المقام الأول.

هل لا تزال JS ذات ترابط واحد؟نعم، لن يتغير هذا (الطريقة الوحيدة لتحقيق تعدد العمليات في JS هي استخدام Web Workers).

هل يغير سلاح الجو الملكي البريطاني أي شيء؟ليس في هذا المجال - إنه بديل أكثر دقة وأداءً لـ setTimeout ويتم مزامنته بشكل مختلف ولكن هذا كل شيء.وسوف تعاني من نفس القيود كما هو الحال مع setTimeout عدم القدرة على التشغيل إذا كان النطاق مشغولاً (وبالتالي request* جزء من الاسم لا يتضمن أي ضمان) ولكن عند تشغيله، سيكون متزامنًا مع معدل تحديث الشاشة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top