في JS ، إذا كنت تخطط لاستخدام SetInterval للعد التنازلي والتوقيت والوظائف الأخرى ، فغالبًا ما تكون غير دقيقة ، لأن وظيفة رد الاتصال في SetInterval لا يتم تنفيذها فور الوصول إلى الوقت ، ولكن لن يتم تنفيذها حتى تكون موارد الحوسبة في النظام الخمول. لم يتم بدء وقت الزناد التالي بعد تنفيذ وظيفة رد الاتصال SetInterval. لذلك ، إذا كانت الحسابات التي تم تنفيذها في SetInterval تستغرق وقتًا طويلاً للغاية ، أو أن هناك مهام أخرى تستغرق وقتًا طويلاً يتم تنفيذها ، فسيصبح توقيت SetInterval غير دقيق بشكل متزايد ولديه تأخير خطير للغاية.
يمكن أن يوضح الرمز التالي هذه المشكلة
نسخة الكود كما يلي:
var startTime = date date (). getTime () ؛
var count = 0 ؛
// مهام تستغرق وقتا طويلا
setInterval (function () {
var i = 0 ؛
بينما (i ++ <100000000) ؛
} ، 0) ؛
setInterval (function () {
count ++ ؛
console.log (date date (). getTime () - (startTime + count * 1000)) ؛
} ، 1000) ؛
يقوم الكود بإخراج وقت تشغيل SetInterval وتأخير المللي ثانية التي يجب تشغيلها بشكل صحيح.
نسخة الكود كما يلي:
176
340
495
652
807
961
1114
1268
1425
1579
1734
1888
2048
2201
2357
2521
2679
2834
2996
......
يمكن أن نرى أن التأخير يزداد أسوأ وأسوأ.
من أجل استخدام وظائف توقيت دقيقة نسبيًا في JS ، يمكننا
نسخة الكود كما يلي:
var startTime = date date (). getTime () ؛
var count = 0 ؛
setInterval (function () {
var i = 0 ؛
بينما (i ++ <100000000) ؛
} ، 0) ؛
وظيفة ثابتة () {
count ++ ؛
var offset = new date (). getTime () - (starttime + count * 1000) ؛
var nextime = 1000 - إزاحة ؛
إذا (التالي <0) Nextime = 0 ؛
setTimeout (ثابت ، في الوقت التالي) ؛
console.log (date date (). getTime () - (startTime + count * 1000)) ؛
}
setTimeout (ثابت ، 1000) ؛
في الكود ، يتم حساب الفجوة بين الوقت الحالي والوقت الدقيق عن طريق طرح 1000 (أي وقت الفترة) ، وبالتالي تصحيح تأخير المشغل الحالي.
أدناه هو الإخراج
نسخة الكود كما يلي:
186
200
230
271
158
899
900
899
900
899
899
899
902
899
418
202
232
266
145
174
192
214
242
268
149
179
214
......
يمكن ملاحظة أنه على الرغم من أن وقت الزناد ليس دقيقًا تمامًا ، حيث يتم تصحيح كل مشغل في الوقت المناسب ، لا يوجد تراكم خطأ.