setTimeout
setTimeout(fun,time),是一个延迟执行的函数,有 V8、QuickJS 开发经验的童鞋可能尝试过在引擎上执行 setTimeout,发现是会报错的,对于前端童鞋而言,setTimeout 不是一个很常见的函数吗?在浏览器上可以正常工作,为何在 V8 引擎上无法正常使用?
实际上 setTimeout 不是 ECMAScript 的一部分,它是由浏览器实现的,基于 V8 的 Node.js 也同样实现了这个函数,所以作为一个纯净的 JS 引擎就不会有这个函数。
Event Queue
我们都知道 JavaScript 是属于单线程模式的,就是说单个浏览器窗口的 JavaScript 代码是运行在一个线程。有些人可能会有疑问,既然是单线程,如何实现网络请求呢,鼠标点击事件又是如何实现的呢?那么不得不谈谈单线程模式中的事件队列,几乎所有的单线程模式都是通过事件队列实现,包括 Flutter、Android 主线程等。当有事件进来,比如鼠标操作,键盘输入等,就会放到事件队列,事件队列会根据事件的入栈顺序响应任务。
回答上面网络请求的问题,虽然浏览器为每一个窗口只分配了一个线程,但是浏览器本身并不是单线程的,网络请求实际上是另开辟了一个新的线程用于请求请求,请求到内容后会把结果放入事件队列。
setTimeout方法实际上也是把回调函数放入事件队列,可执行的事件到就会触发函数的执行。
多线性 Worker
虽然 JS 是单线程的,但是浏览器现在是支持 worker 功能,可以开辟一个新的线程执行耗时任务,但是浏览器的 worker 和 窗口的线程是独立的,意味着 worker 和 窗口是无法共享变量,也无法操作 DOM等,只可以通过 postMessage 函数把消息传递到窗口的js环境。
网友评论