JavaScript单线程机制与setTimeout执行原理的介绍(附代码)
本篇文章给大家带来的内容是关于JavaScript单线程机制与setTimeout执行原理的介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
Javascript 引擎单线程机制
首先明确,JavaScript引擎是单线程机制。
JavaScript 是单线程执行的,无法同时执行多段代码。当某一段代码正在执行的时候,所有后续的任务都必须等待,形成一个任务队列。一旦当前任务执行完毕,再从队列中取出下一个任务,这也常被称为 “阻塞式执行”。
可以理解为:只有在JS线程中没有任何同步代码要执行的前提下才会执行异步代码
所以一次鼠标点击,或是计时器到达时间点,或是 Ajax 请求完成触发了回调函数,这些事件处理程序或回调函数都不会立即运行,而是立即排队,一旦线程有空闲就 执行。假如当前 JavaScript 线程正在执行一段很耗时的代码,此时发生了一次鼠标点击,那么事件处理程序就被阻塞,用户也无法立即看到反馈,事件处理程序会被放入任务队列,直到前面的代码结束以后才会开始执行。如果代码中设定了一个 setTimeout,那么浏览器便会在合适的时间,将代码插入任务队列,如果这个时间设为 0,就代表立即插入队列,但不是立即执行,仍然要等待前面代码执行完毕。所以 setTimeout 并不能保证执行的时间,是否及时执行取决于 JavaScript 线程是拥挤还是空闲。浏览器的多线程机制与事件循环(event loop)
首先明确,浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:
javascript 引擎线程
GUI 渲染线程
浏览器事件触发线程
JavaScript 引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序
javascript 引擎是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个JS线程在运行JS程序。
GUI渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。但需要注意 GUI渲染线程与JS引擎是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。
事件触发线程,当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可来自 JavaScript 引擎当前执行的代码块如 setTimeOut,也可来自浏览器内核的其他线程如鼠标点击、AJAX 异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。(当线程中没有执行任何同步代码的前提下才会执行异步代码)
事件循环(event loop): 是用来管理我们的异步代码的,它会把它们放在一个线程池当中
JavaScript中setTimeout的实现原理
首先明确,setTimeout函数是异步代码,但其实setTimeout并不是真正的异步操作
由于JS线程的工作机制:当线程中没有执行任何同步代码的前提下才会执行异步代码,setTimeout是异步代码,所以setTimeout只能等js空闲才会执行
前面提到过,如果代码中设定了一个 setTimeout,那么浏览器便会在合适的时间,将代码插入任务队列,如果这个时间设为 0,就代表立即插入队列,但不是立即执行,仍然要等待前面代码执行完毕。所以 setTimeout 并不能保证执行的时间,是否及时执行取决于 JavaScript 线程是拥挤还是空闲。
也就是说setTimeout只能保证在指定的时间过后将任务(需要执行的函数)插入队列等候,并不保证这个任务在什么时候执行。执行javascript的线程会在空闲的时候,自行从队列中取出任务然后执行它。javascript 通过这种队列机制,给我们制造一个异步执行的假象。
有时setTimeout中的代码会很快得到执行,我们会感觉这段代码是在异步执行,这是因为 javascript 线程并没有因为什么耗时操作而阻塞,所以可以很快地取出排队队列中的任务然后执行它。
实例分析
在具备了上述理论基础之后,我们对以下几个实例进行分析:
===========================================
var t = true; window.setTimeout(function (){ t = false; },1000); while (t){} alert('end');
运行结果:程序陷入死循环,t = false
得不到执行,因此 alert('end')
不会执行。
解析:
JS是单线程的,所以会先执行 while(t){} 再 alert,但这个循环体是死循环,所以永远不会执行alert。
为什么不执行 setTimeout?是因为JS的工作机制是:当线程中没有执行任何同步代码的前提下才会执行异步代码,setTimeout是异步代码,所以 setTimeout 只能等JS空闲才会执行,但死循环是永远不会空闲的,所以 setTimeout 也永远得不到执行。
===========================================
var start = new Date(); setTimeout(function(){ var end = new Date(); console.log("Time elapsed: ", end - start, "ms"); }, 500); while (new Date - start <= 1000){}
运行结果:"Time elapsed: 1035 ms" (这里的1035不准确 但是一定是大于1000的)
解析:
JS是单线程 setTimeout 异步代码 其回调函数执行必须需等待主线程运行完毕
当while循环因为时间差超过 1000ms 跳出循环后,setTimeout 函数中的回调才得以执行
===========================================
for(var i=0;i<10;i++){ setTimeout(function() { console.log(i); }, 0); }
运行结果:输出10个10
解析:JS单线程 setTimeout 异步代码 任务队列
问:如何修改可以使上述代码输出 0123456789
自执行函数 或 使用ES6中的let关键字
// 自执行函数 形成闭包 记忆其被创建时的环境 for(var i=0;i<10;i++){ setTimeout((function() { console.log(i); })(), 0); }
setTimeout(0)函数的作用
现在我们了解了setTimeout函数执行的原理,那么它有什么作用呢?
setTimeout函数增加了Javascript函数调用的灵活性,为函数执行顺序的调度提供极大便利。
简言之,改变顺序,这正是setTimeout(0)的作用。
使用场景示例:
<input type="text" onkeydown="show(this.value)"> <p></p> <script type="text/javascript"> function show(val) { document.getElementsByTagName('p')[0].innerHTML = val; } </script>
这里绑定了 keydown 事件,意图是当用户在文本框里输入字符时,将输入的内容实时地在
中显示出来。但是实际效果并非如此,可以发现,每按下一个字符时,
中只能显示出之前的内容,无法得到当前的字符。
修改代码:
<input type="text" onkeydown="var self=this; setTimeout(function(){show(self.value)}, 0)"> <p></p> <script type="text/javascript"> function show(val) { document.getElementsByTagName('p')[0].innerHTML = val; } </script>
这段代码使用setTimeout(0)就可以实现需要的效果了。
这里其实涉及2个任务,1个是将键盘输入的字符回写到输入框中,一个是获取文本框的值将其写入p中。第一个是浏览器自身的默认行为,一个是我们自己编写的代码。很显然,必须要先让浏览器将字符回写到文本框,然后我们才能获取其内容写到p中。改变顺序,这正是setTimeout(0)的作用。
其他应用场景:有时候,加载一些广告的时候,我们用setTimeout实现异步,好让广告不会阻塞我们页面的渲染。
setTimeout 和 setInterval 在执行异步代码的时候有着根本的不同
如果一个计时器被阻塞而不能立即执行,它将延迟执行直到下一次可能执行的时间点才被执行(比期望的时间间隔要长些)
如果setInterval回调函数的执行时间将足够长(比指定的时间间隔长),它们将连续执行并且彼此之间没有时间间隔。
本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的JavaScript视频教程栏目!
Atas ialah kandungan terperinci JavaScript单线程机制与setTimeout执行原理的介绍(附代码). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian Pengenalan: Dengan perkembangan teknologi yang berterusan, teknologi pengecaman pertuturan telah menjadi bahagian penting dalam bidang kecerdasan buatan. Sistem pengecaman pertuturan dalam talian berdasarkan WebSocket dan JavaScript mempunyai ciri kependaman rendah, masa nyata dan platform merentas, dan telah menjadi penyelesaian yang digunakan secara meluas. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian.

WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

Pengenalan kepada cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata: Dengan populariti Internet dan kemajuan teknologi, semakin banyak restoran telah mula menyediakan perkhidmatan pesanan dalam talian. Untuk melaksanakan sistem pesanan dalam talian masa nyata, kami boleh menggunakan teknologi JavaScript dan WebSocket. WebSocket ialah protokol komunikasi dupleks penuh berdasarkan protokol TCP, yang boleh merealisasikan komunikasi dua hala masa nyata antara pelanggan dan pelayan. Dalam sistem pesanan dalam talian masa nyata, apabila pengguna memilih hidangan dan membuat pesanan

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian Dalam era digital hari ini, semakin banyak perniagaan dan perkhidmatan perlu menyediakan fungsi tempahan dalam talian. Adalah penting untuk melaksanakan sistem tempahan dalam talian yang cekap dan masa nyata. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian dan memberikan contoh kod khusus. 1. Apakah itu WebSocket? WebSocket ialah kaedah dupleks penuh pada sambungan TCP tunggal.

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Pengenalan: Hari ini, ketepatan ramalan cuaca sangat penting kepada kehidupan harian dan membuat keputusan. Apabila teknologi berkembang, kami boleh menyediakan ramalan cuaca yang lebih tepat dan boleh dipercayai dengan mendapatkan data cuaca dalam masa nyata. Dalam artikel ini, kita akan mempelajari cara menggunakan teknologi JavaScript dan WebSocket untuk membina sistem ramalan cuaca masa nyata yang cekap. Artikel ini akan menunjukkan proses pelaksanaan melalui contoh kod tertentu. Kami

Penggunaan: Dalam JavaScript, kaedah insertBefore() digunakan untuk memasukkan nod baharu dalam pepohon DOM. Kaedah ini memerlukan dua parameter: nod baharu untuk dimasukkan dan nod rujukan (iaitu nod di mana nod baharu akan dimasukkan).

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest

JavaScript ialah bahasa pengaturcaraan yang digunakan secara meluas dalam pembangunan web, manakala WebSocket ialah protokol rangkaian yang digunakan untuk komunikasi masa nyata. Menggabungkan fungsi berkuasa kedua-duanya, kami boleh mencipta sistem pemprosesan imej masa nyata yang cekap. Artikel ini akan memperkenalkan cara untuk melaksanakan sistem ini menggunakan JavaScript dan WebSocket, dan memberikan contoh kod khusus. Pertama, kita perlu menjelaskan keperluan dan matlamat sistem pemprosesan imej masa nyata. Katakan kita mempunyai peranti kamera yang boleh mengumpul data imej masa nyata
