事件循环和 Job Queue(事件队列)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事件循环和 Job Queue(事件队列)相关的知识,希望对你有一定的参考价值。
单线程程序的弊端
var res = ajax(...)
//undefine
标准的 ajax请求不会同步完成,应该用回调的方式进行赋值,同步 ajax 的弊端就是单线程程序的弊端。应该把操作放在 ajax 的回调中进行。
可以用 setTimeout 的方式实现异步。
什么是事件循环机制呢?
javascript 引擎并不是单独执行的,都运行在一个托管环境当中,托管环境都有一个共同的特点--------具有一个称为事件循环的内置机制,这个机制可以处理程序多个块的执行。所以我们可以这样说,JavaScript 引擎是JavaScript 的一个任意执行的环境,而托管环境是安排JavaScript 事件执行的一个周边环境(对于“|周边”这个词,我抱有一些疑问,是否是指 JavaScript 事件的一个控制 )
明白了上面说的,我们就理解了一个 JavaScript 程序中,异步请求的一个执行逻辑:
首先你在你的 ajax 请求中设置了一个 callback,JavaScript 引擎会告诉托管环境,程序现在暂停执行,等你完成了数据的请求,拿到了数据之后,再继续执行程序。这是浏览器就会设置一个监听机制来响应网络请求回来的数据,拿到数据之后,浏览器再去执程序,将请求回来的数据插入到事件循环中来调度回调函数。
讲了这么多,我们终于提到 “事件循环机制” 这个词了,为什么要做上面的那些铺垫了,这是为了能让你更好地理解什么是事件循环机制。下面我们来正式介绍事件循环机制。
事件循环有一个任务--------监视调用堆栈和回调队列。如果调用堆栈是空的,它将从队列中取出第一个事件,并将其推到调用堆栈,堆栈会去运行被推进去的事件。这也一个任务迭代的过程,被称为事件循环中的一个 tick 。每个事件都只是一个回调函数。
举个例子,有下面这些程序:
console.log("你好啊!");
setTimeout(function(){
console.log("嘿嘿嘿");
}, 5000)
console.log("你好啊!");
程序按照顺序进行执行,执行 setTimeout 时,浏览器作为一个上面我们所提到的周边环境,会安排事件的执行的,浏览器会为 setTimeout 创建一个计时器,处理这个倒计时。计时器执行 5000ms 之后,会将 setTimeout 中的回调函数推到调用堆栈中,并被执行,然后回调中的程序被添加到调用堆栈。
在 ES6 标准出来之前,JavaScript 并没有一个清晰的关于异步的概念。ES6 中指定了事件循环应该如何工作,这就明确了异步不再只是JavaScript 托管环境的职责。ES6 中具体如何执行异步的呢?这就要到 ES6 中的 Promise,通过Promise可以实现 JavaScript 程序自身对于事件循环队列的直接控制。
以上是关于事件循环和 Job Queue(事件队列)的主要内容,如果未能解决你的问题,请参考以下文章