本文实例讲述了node.js中对Event Loop事件循环的理解与应用。分享给大家供大家参考,具体如下:
javascript是单线程的,所以任务的执行都需要排队,任务分为两种,一种是同步任务,一种是异步任务。
同步任务是进入主线程上排队执行的任务,上一个任务执行完了,下一个任务才会执行。
异步任务是不进入主线程,而是进入一个 "任务队列" 里,"任务队列" 通知主线程,该异步任务才会进入主线程执行。
任务的运行机制如下:
1、所有同步任务在主线程上执行,形成一个 "执行栈",注意栈是先进后出的。
2、主线程外,有一个 "任务队列" ,只要异步任务处理完有结果了,就在 "任务队列" 中放置一个事件,注意队列是先进先出的。
3、一旦 "执行栈" 中所有同步任务执行完毕。系统读取 "任务队列" 中的事件,对应的异步任务。放入 "执行栈" 中,开始执行。
4、主线程不断重复第三步,这种循环从 "任务队列" 中读取事件处理的这种运行机制称为Event Loop(事件循环)。
"执行栈" 中的同步代码总是比 "任务队列"中的异步任务之前运行。
function fun() { setTimeout(function () { console.log('异步任务'); }, 0); console.log(1); console.log(2); console.log(3); console.log(4); console.log(5);}fun();
上面的代码,console.log代码写在setTimeout后面,但仍然先执行。
"任务队列" 是一个队列,队列的特性是先进先出。看下面代码:
function fun() { console.log(1); setTimeout(function () { console.log(2); setTimeout(function () { console.log(3); }, 0); }, 0); console.log(4);}fun();
输出结果为 1 4 2 3,打印 2 的setTimeout任务比打印 3 的setTimeout任务先进入队列,所以会先运行。
对于异步操作,像ajax,只有操作成功后返回结果,才会进入 "任务队列" 中,而不是调用的时候就放入队列中。看下面代码:
<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8"> <title>Title</title></head><body><script> function ajax() { var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://mail.163.com/', true); xhr.send(); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.responseText); } }; } function fun() { console.log(1); ajax(); setTimeout(function () { console.log(2); }, 1000); console.log(3); } fun();</script></body></html>
ajax() 与 setTimeout 谁先进入队列,谁先输出,是需要看两者消耗时间,谁更短。时间短的会先进入队列先运行。
新闻热点
疑难解答
图片精选