想了解JavaScript事件循环,首先要知道,JavaScript分为同步任务和异步任务。同步任务都在主线程(这里的主线程就是JS引擎线程)上执行,会形成一个执行栈,主线程之外,事件触发线程管理着一个任务队列,只要异步任务有了运行结果,就在任务队列之中放一个事件回调。
一旦执行栈中的所有同步任务执行完毕(也就是JS引擎线程空闲了),系统就会读取任务队列,将可运行的异步任务(任务队列中的事件回调,只要任务队列中有事件回调,就说明可以执行)添加到执行栈中,开始执行。
我们来看一段简单的代码:
let setTimeoutCallBack = function() {
console.log('我是定时器回调');
};
let httpCallback = function() {
console.log('我是http请求回调');
}
// 同步任务
console.log('我是同步任务1');
// 异步定时任务
setTimeout(setTimeoutCallBack,1000);
// 异步http请求任务
ajax.get('/info',httpCallback);
// 同步任务
console.log('我是同步任务2');
上述代码执行过程
JS是按照顺序从上往下依次执行的,可以先理解为这段代码时的执行环境就是主线程,也就是也就是当前执行栈。
首先,执行console.log('我是同步任务1');
接着,执行到setTimeout时,会移交给定时器线程,通知定时器线程 1s 后将 setTimeoutCallBack 这个回调交给事件触发线程处理,在 1s 后事件触发线程会收到 setTimeoutCallBack 这个回调并把它加入到事件触发线程所管理的事件队列中等待执行;
接着,执行http请求,会移交给异步http请求线程发送网络请求,请求成功后将 httpCallback 这个回调交由事件触发线程处理,事件触发线程收到 httpCallback 这个回调后把它加入到事件触发线程所管理的事件队列中等待执行;
再接着执行console.log('我是同步任务2');
至此主线程执行栈中执行完毕,JS引擎线程已经空闲,开始向事件触发线程发起询问,询问事件触发线程的事件队列中是否有需要执行的回调函数,如果有将事件队列中的回调事件加入执行栈中,开始执行回调,如果事件队列中没有回调,JS引擎线程会一直发起询问,直到有为止。
到了这里我们发现,浏览器上的所有线程的工作都很单一且独立,非常符合单一原则;
定时触发线程只管理定时器且只关注定时不关心结果,定时结束就把回调扔给事件触发线程;
异步http请求线程只管理http请求同样不关心结果,请求结束把回调扔给事件触发线程;
事件触发线程只关心异步回调入事件队列;
而我们JS引擎线程只会执行执行栈中的事件,执行栈中的代码执行完毕,就会读取事件队列中的事件并添加到执行栈中继续执行,这样反反复复就是我们所谓的事件循环(Event Loop)。
首先,执行栈开始顺序执行;
判断是否为同步,异步则进入异步线程,最终事件回调给事件触发线程的任务队列等待执行,同步继续执行;
执行栈空,询问任务队列中是否有事件回调;
任务队列中有事件回调则把回调加入执行栈末尾继续从第一步开始执行;
任务队列中没有事件回调则不停发起询问。
上述的内容就是JavaScript事件循环的整个完整的步骤,我们稍加分析就能理解JavaScript事件循环的本质,我们的动力节点在线上,像这样的好文章还有很多,而且还有大量名师讲解的免费视频课程,这么好的Java学习网站你值得拥有!
代码小兵49806-11 15:28
代码小兵49806-11 15:51
代码小兵49806-11 16:22
代码小兵51603-29 17:28
暴风城-小飞04-06 20:49