本文实例讲述了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 谁先进入队列,谁先输出,是需要看两者消耗时间,谁更短。时间短的会先进入队列先运行。
setTimeout 与 setInterval 运行机制一样,都是在指定时间把事件插入到 "任务队列" 尾部。区别是前者只执行一次,后者可反复执行。
node.js 还为我们提供了,process.nextTick 和 setImmediate 与 "任务队列" 有关的方法。
process.nextTick 会把回调函数放在当前 "执行栈" 的尾部。也就是说是在读取 "任务队列" 之前运行。
function fun() { console.log(1); setTimeout(function () { console.log(2); }, 0); process.nextTick(function () { console.log(3); process.nextTick(function () { console.log(4); }); }); process.nextTick(function () { console.log(5); }); console.log(6); } fun();
上面的代码会输出 1 6 3 5 4 2 ,注意process.nextTick会把回调函数放在 "执行栈" 的尾部。
同步代码最先输出 1 6,然后 3 的先放入尾部,然后 5 的跟在 3 后面。3先执行,然后把 4 放入到 5 的后面。5执行完后,再执行4,最后读取 "任务队列" 中的输出2。
setImmediate 会把回调函数放在当前 "任务队列" 的尾部。也就是下一次事件循环Event Loop时执行。
function fun() { console.log(1); setTimeout(function () { console.log(2); }, 0); setImmediate(function () { console.log(3); }); console.log(4); } fun();
上面的代码是会输出 1 4 2 3 还是 1 4 3 2 是不确定的,因为setTimeout 与 setImmediate 都会在下一次事件循环Event Loop中触发,所以输出是不确定的。
希望本文所述对大家node.js程序设计有所帮助。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
更新日志
- 群星《乘风2024 第6期》[FLAC/分轨][170.72MB]
- 陈立强1995-我爱你胜过这世界[福茂][WAV+CUE]
- 群星-《2014年十大发烧唱片精选HQCD》[低速原抓WAV+CUE]
- 群星2013-青春缤纷辑压箱宝大公开3CD2[新加坡限量版][WAV整轨]
- 林育群.2013-BalladShow(日本版)【环球】【WAV+CUE】
- 陈加洛.1992-痛到感觉不到【宝丽金】【WAV+CUE】
- 群星.2023-宿命之敌电视剧原声带【韶愔音乐】【FLAC分轨】
- 東京事変-大発見[FLAC+CUE]
- 椎名林檎-三文ゴシップ[FLAC+CUE]
- 2024年08月04日
- 裘德《裘德「最后的水族馆」演唱会LIVE》[320K/MP3][228.89MB]
- 裘德《裘德「最后的水族馆」演唱会LIVE》[24bit 48kHz][FLAC/分轨][2.08G]
- 基因三重奏《如果你什么都不说 音乐会现场录音》[320K/MP3][145.37MB]
- 孟庭苇.1996-月亮说话(2020环球24KGOLD限量版)【上华】【WAV+CUE】
- 群星.1997-新艺宝优质音响系列·国语精选监听版【新艺宝】【WAV+CUE】