在浏览器中,事件做为一个极为重要的机制,给予JavaScript响应用户操做与DOM变化的能力。在NodeJS中。异步事件驱动模型则是提升并发能力的基础。javascript
操做系统处理键盘等硬件输入就是经过中断来进行的。这个方式的优势是即便没有多线程,咱们也可以放心地运行咱们的代码,CPU收到中断信号以后本身主动地转去运行对应的中断处理程序,处理完毕后会恢复原来的代码的运行环境继续运行。java
这样的方式需要硬件的支持。通常来讲都会被操做系统封装起来。浏览器
轮询方式的一个缺点就是:假设在主线程的消息循环里进行耗时操做。程序就没法及时响应新的消息。多线程
不论是Node仍是浏览器中,都有setTimeout和setInterval这两个定时器函数。并且其工做特色基本一样。并发
JavaScript中的定时器并不一样于计算机底层的定时中断。异步
中断到来时,当前运行代码会被打断。转去运行定时中断处理函数。函数
而JavaScript的定时器到时,假设当前运行线程没有正在运行的代码。则运行对应的回调函数;假设当前有代码在运行中,JavaScript引擎既不会中断当前代码转去运行回调,也不会开新的线程运行回调,而是当前代码运行完成以后才去处理。高并发
console.time("setTimoutLabel"); //标记时间開始 setTimeout(function() { console.timeEnd("setTimoutLabel"); //标记时间结束 }, 100); for (var i = 0; i < 100000; i++) { }
运行上面的代码。可以看到终于输出的时间并不是100ms左右,而是数秒。post
这说明在循环完毕以前,定时回调函数确实没有被运行。而是推迟到了循环结束。实际上在JavaScript代码运行中,全部的事件都没法获得处理,必须等到当前代码全部完毕,才干去处理新的事件。这就是为何在浏览器中运行耗时JavaScript代码时,浏览器会失去响应。spa
1. javascript引擎仅仅有一个线程,迫使异步事件仅仅能增长队列去等待运行。
2. 在运行异步代码的时候,假设定时器被正在运行的代码堵塞了,它将会进入队列的尾部去等待运行直到下一次可能运行的时间出现(可能超过设定的延时时间)。setTimeout 和setInterval 是有着本质差异的:setTimeout 这段代码会在每次回调函数运行以后至少需要延时“指定延迟毫秒值”再去执行(多是不少其它,但是不会少)。但是setInterval会每隔“指定延迟毫秒值”就去尝试运行一次回调函数。不管上一个回调函数是否是还在运行。