JavaScript موضوع واحد
يرتبط خيوط JavaScript الفردية بغرضها. كلغة البرمجة النصية للمتصفح ، الغرض الرئيسي من JavaScript هو التفاعل مع المستخدمين وتشغيل DOM. هذا يحدد أنه لا يمكن أن يكون سوى خيوط واحدة ، وإلا فإنه سيؤدي إلى مشاكل تزامن معقدة للغاية. على سبيل المثال ، لنفترض أن JavaScript لديها مؤشر ترابط في نفس الوقت ، ويضيف مؤشر ترابط واحد محتوى على عقدة DOM معينة ، ويحذف مؤشر الترابط الآخر هذه العقدة ، أي مؤشر ترابط يجب أن يأخذه المستعرض في هذا الوقت؟ لذلك ، من أجل تجنب التعقيد ، يعد JavaScript موضوعًا واحدًا من ولادته ، والذي أصبح الميزة الأساسية لهذه اللغة ولن يتغير في المستقبل.
مهام قائمة الانتظار
يعني الخيوط الفردية أن جميع المهام تحتاج إلى قائمة الانتظار ، وسيتم تنفيذ المهمة السابقة قبل تنفيذ المهمة التالية. إذا استغرقت المهمة السابقة وقتًا طويلاً ، فيجب أن تنتظر المهمة التالية.
سائق الحدث غير المتزامن
العديد من السلوكيات في المتصفح غير متزامنة ، مثل: الفأر النقر فوق الحدث ، حدث سحب حجم النافذة ، حدث Timer Trigger ، رد اتصال XMLHTTPRequest ، وما إلى ذلك. عند حدوث حدث غير متزامن ، فإنه يدخل قائمة انتظار الحدث. يحتوي المتصفح على حلقة رسائل كبيرة داخلية ، حلقة حدث ، والتي ستقوم باستطلاع قوائم قوائم الأحداث الكبيرة وأحداث المعالجة. على سبيل المثال ، يكون المتصفح مشغولًا حاليًا بمعالجة حدث OnClick ، ثم يحدث حدث آخر (مثل الحجم المتمثل في النوافذ) ، ويتم وضع هذا الحدث غير المتزامن في قائمة انتظار الحدث وينتظر المعالجة. سيتم تنفيذ هذا الحدث فقط عند اكتمال المعالجة السابقة وهي مجانية.
حلقة الحدث
JavaScript أحادية الخيوط ، لكن المتصفح غير متطابق واحد
سيكون للمتصفح على الأقل بعض العمليات التالية
1. متصفح واجهة المستخدم الرسومية.
2. موضوع محرك JavaScript
3. موضوع زناد توقيت المتصفح
4.
5. المستعرض HTTP موضوع طلب غير متزامن
نظرًا لأن محرك JavaScript متمرس ، يتم الضغط على الكود أولاً إلى قائمة الانتظار ثم يتم تشغيله بواسطة المحرك بطريقة أول في الأول. سيتم أيضًا وضع وظائف معالجة الأحداث ووظائف تنفيذ الموقت في قائمة الانتظار هذه ، ثم استخدام حلقة لا حصر لها لاستخراج الوظائف باستمرار من رأس الفريق لتنفيذها. هذه حلقة الحدث.
باختصار ، يعتبر JS متسلسلًا واحدًا ، لكن المتصفح متعدد الخيوط. عند مواجهة أشياء غير متزامنة ، سيضع المتصفح رد الاتصال غير المتزامن في حلقة الحدث. عندما لا يكون موضوع JS مشغولاً ، اقرأ حلقة الحدث.
مبدأ المؤقت
كيفية استخدام المؤقت
setTimeout (FN ، تأخير)
SetInterval (FN ، Delay)
FN هي وظيفة أو سلسلة ، والتأخير هو وقت التأخير ، والوحدة هي مللي ثانية
هناك الأشياء التالية التي يجب ملاحظتها
1. على الرغم من أن FN يمكن أن يكون سلسلة ، إلا أنه لا ينصح به أبدًا لاستخدامها مثل هذا.
2. إذا كانت هناك هذه الوظيفة في FN ، فسيشير هذا إلى النافذة عند التنفيذ.
إذا فهمت خيط JS الفردي وحلقة الحدث جيدًا ، فسيكون من السهل فهم مبدأ المؤقت.
إذا تم تعيين مؤقت ، عند الوصول إلى وقت التأخير ، سيضع المتصفح حدث التنفيذ المتأخر في حلقة الحدث. عندما يحين الوقت ، إذا كان مؤشر ترابط JS في وضع الخمول ، فسيتم تنفيذه (وبالتالي فإن دقة المؤقت غير دقيقة)
قرأت مقالًا عن الفرق بين SetTimeOut و SetInterval الذي دائمًا وظائف الاستطلاع. الرمز كما يلي
نسخة الكود كما يلي:
setTimeout (function () {
setTimeout (الحجج. callee ، 100)
} ، 100)
setInterval (function () {} ، 1000)
المعنى العام للمقال هو أن SetTimeOut يبدأ الموقت التالي بعد تنفيذ وظيفة رد الاتصال ، لذلك يجب تنفيذها على فترات ، بينما يتم تنفيذ SetInterval طوال الوقت. إذا واجهت مؤشر ترابط JS يستمر في التنفيذ ، فيمكنك إضافة عمليات استرداد متعددة في حلقة الحدث. عندما لا يكون موضوع JS مشغولاً ، سيتم تنفيذ عمليات إعدام متعددة واحدة تلو الأخرى.
بعد الاختبار ، وجد أن SetInterval هو على فاصل معين ، بغض النظر عن IE و FF و Chrome و Opera و Safari.
رمز الاختبار كما يلي
نسخة الكود كما يلي:
setInterval (function () {
xx.innerhtml = xx.innerhtml+1 ؛
} ، 100) ؛
لـ (var i = 0 ؛ i <6000000 ؛ i ++) {
xx.offsetwidth
}
setTimeout (function () {
تصحيح الأخطاء
} ، 10)
عندما لا تزال نقاط التوقف مطبوعة فقط 1
قضايا دقة المؤقت
بسبب موضوع JS الفردي ، إذا واجهت الانشغال ، فسيكون المؤقت بالتأكيد غير دقيق ، وسيكون بالتأكيد أطول وأطول. يبدو أن هذا غير قابل للحل ، لا حل.
مشكلة دقة أخرى هي الحد الأدنى للفاصل الزمني setTimeout (المرح ، 0)
عندما لا يكون مؤشر ترابط JS مشغولاً ، فمن المستحيل تنفيذها مباشرة بعد 0 ثانية. هناك دائمًا فاصل زمني أدنى ، ولا يزال كل متصفح مختلفًا. لم يتم اختبار هذا.
قرأت مقالة عن معيار W3C. الحد الأدنى لوقت تنفيذ المؤقت هو 4 مللي ثانية. لا توجد طريقة للتحقق من المصدر إذا لم تتمكن من العثور عليه! ! !
بعض التحسينات المتعلقة بالوقت
لا تزال هناك بعض التحسينات عند إنشاء أجهزة ضبط الوقت
1. على سبيل المثال ، إذا قمت بربط نافذة. عند مسح التنفيذ التالي ، سيقلل التنفيذ المتكرر.
الكود الزائف كما يلي
نسخة الكود كما يلي:
var timer ؛
وظيفة r () {
ClearTimeout (مؤقت) ؛
Timer = setTimeOut (function () {
// افعل شيئًا
} ، 150) ؛
}
2. عندما يتم سحب شريط التمرير لأسفل ، فهو أيضًا قليلاً. على سبيل المثال ، يجب أن يكون للحمل الكسول للصورة مؤقتًا لتجنب الحسابات المفرطة.
3. عندما تكون هناك أماكن متعددة حيث تكون هناك حاجة إلى أجهزة ضبط الوقت ، يمكنك دمجها في مؤقت. الفاصل الزمني هو أصغر واحد. ثم يتم محشوة وظيفة رد الاتصال التي يجب تنفيذها في الصفيف. عندما يتم الوصول إلى الفاصل الزمني ، تكرار الصفيف للتنفيذ.
عرض صغير
نسخة الكود كما يلي:
<! doctype html>
<html>
<head>
<meta charset = "utf-8" />
<style>
.wrap {العرض: 80 ٪ ؛ الهامش: 30 بكسل Auto ؛ الحدود: 1px الصلبة #CCC ؛ الحشو: 20 بكسل ؛}
.c {الحدود: 1px solid #ccc ؛ الارتفاع: 30 بكسل ؛ هامش القاع: 20 بكسل ؛}
</style>
</head>
<body>
<div id = "xx"> </viv>
<viv>
<div id = "a1"> 0 </viv>
<div id = "a2"> 0 </viv>
<div id = "a3"> 0 </viv>
<div id = "a4"> 0 </viv>
</div>
<script src = "http://static.paipaiimg.com/paipai_h5/js/ttj/zepto.min.js"> </script>
<script type = "text/javaScript">
var runtime = {
خيارات: {
الخطوة: 1000
} ،
عروض الاسترجاعات: [] ،
AddCallbacks: [] ،
البدء: خطأ ،
مؤقت: فارغ ،
تمديد: function () {
var target = mations [0] || {} ، i = 1 ، length = ediuments.length ، Options ؛
if (typeof target! = "Object" && typeof target! = "function")
الهدف = {} ؛
لـ (؛ i <length ؛ i ++)
if ((خيارات = الوسائط [i])! = null)
لـ (var name in Options) {
var copy = Options [name] ؛
إذا (الهدف === نسخة)
يكمل؛
إذا (نسخة! == غير محددة)
الهدف [الاسم] = نسخة ؛
}
الهدف الإرجاع ؛
} ،
init: وظيفة (خيارات) {
$ .extend (هذا ، this.options ، الخيارات || {}) ؛
} ،
إضافة: وظيفة (متعة ، خيارات) {
الخيارات = الخيارات || {} ؛
this.addcallbacks.push ({
المرح: متعة ،
وقت البدء: تاريخ جديد (). GetTime () ،
الخطوة: Options.step || this.step ،
أنا: 1
}) ؛
var self = this ؛
if (! this.start) {
this.callbacks = [متعة] ؛
this.start = true ؛
this.startTime = new date (). getTime () ؛
this.timer = setInterval (function () {
self.done () ؛
} ، this.step) ؛
}
} ،
تم: وظيفة () {
var backbacks = this.callbacks ،
الذات = هذا ،
نيار = [] ؛
دولار.
if (obj.step == self.step) {
obj.fun () ؛
}آخر{
if (obj.i == obj.step/self.step) {
if ((Date ()
obj.fun () ؛
}
obj.i = 1 ؛
}آخر{
obj.i = obj.i + 1 ؛
}
}
}) ؛
دولار.
if (obj.step == self.step) {
if ((Date ()
obj.fun () ؛
callbacks.push (OBJ) ؛
}آخر{
Newarr.push (OBJ) ؛
}
}آخر{
obj.i = obj.i + 1 ؛
callbacks.push (OBJ) ؛
}
}) ؛
this.addcallbacks = Newarr ؛
} ،
واضح: وظيفة () {
ClearInterval (this.timer) ؛
}
}
Runtime.init () ؛
Runtime.add (function () {
a1.innerhtml = ~~ a1.innerhtml+1 ؛
}) ؛
Runtime.add (function () {
a2.innerhtml = ~~ a2.innerhtml+1 ؛
} ، {الخطوة: 2000}) ؛
Runtime.add (function () {
a3.innerhtml = ~~ a3.innerhtml+1 ؛
} ، {الخطوة: 4000}) ؛
Runtime.add (function () {
a4.innerhtml = ~~ a4.innerhtml+1 ؛
} ، {الخطوة: 8000}) ؛
</script>
</body>
</html>
هل لديك أي فكرة عن مؤقت JavaScript؟ اترك لي رسالة إذا كان لديك أي أسئلة.