在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
事件循环在浏览器环境下我们的js有一套自己的事件循环,同样在node环境下也有一套类似的事件循环。 浏览器环境事件循环首先,我们先来回顾一下在浏览器的事件循环: 总结来说:
浏览器环境下的例子: 例子: console.log("1"); setTimeout(() => { console.log("setTimeout"); }, 1); new Promise((res, rej) => { console.log("Promise"); res('PromiseRes') }).then(val => { console.log(val); }) console.log("2"); 分析: node环境事件循环在node中事件循环主要分为六个阶段来实现:
六个阶段图片来自网络
主要阶段: 如果 poll 队列不为空,会遍历回调队列并同步执行,直到队列为空或者达到系统限制 check阶段 (1) setTimeout 和 setImmediate二者非常相似,区别主要在于调用时机不同。 setImmediate 设计在 poll 阶段完成时执行,即 check 阶段,只有在check阶段才会执行; 这两个执行的时机可前可后: // //异步任务中的宏任务 setTimeout(() => { console.log('===setTimeout==='); },0); setImmediate(() => { console.log('===setImmediate===') })
例子2: setTimeout(() => { console.log('===setTimeout==='); },10); setImmediate(() => { console.log('===setImmediate===') })
例子3: const fs = require('fs'); fs.readFile("./any.js", (data) => { setTimeout(() => { console.log('===setTimeout==='); },10); setImmediate(() => { console.log('===setImmediate===') }) });
在第一轮循环中读取文件,在回调中,会进入check阶段进而执行setImmediate,随后timer阶段执行定时器。 (2) process.nextTick这个函数其实是独立于 Event Loop 之外的,它有一个自己的队列,当每个阶段完成后,如果存在 nextTick 队列,就会清空队列中的所有回调函数,并且优先于其他 microtask 执行。 例子1: setTimeout(() => { console.log('timer1') Promise.resolve().then(function() { console.log('promise1') }) }, 0) process.nextTick(() => { console.log('nextTick') process.nextTick(() => { console.log('nextTick') process.nextTick(() => { console.log('nextTick') process.nextTick(() => { console.log('nextTick') }) }) }) }) // nextTick=>nextTick=>nextTick=>nextTick=>timer1=>promise1 例子2: const fs = require('fs'); fs.readFile("./any.js", (data) => { process.nextTick(()=>console.log('process===2')) setTimeout(() => { console.log('===setTimeout==='); },10); setImmediate(() => { console.log('===setImmediate===') }) }); process.nextTick(()=>console.log('process===1')) 练习例子async function async1() { console.log('2') //会等待await执行完 但是不会向下执行 因为下面输入微任务 await async2() console.log('9') } function async2() { console.log('3') } console.log('1') setTimeout(function () { console.log('11') }, 0) setTimeout(function () { console.log('13') }, 300) setImmediate(() => console.log('12')); process.nextTick(() => console.log('7')); async1(); process.nextTick(() => console.log('8')); new Promise(function (resolve) { console.log('4') resolve(); console.log('5') }).then(function () { console.log('10') }) console.log('6') 分析: 例子: async function async1() { console.log('2') //会等待await执行完 但是不会向下执行 因为下面输入微任务 await async2() console.log('9') } function async2() { console.log('3') } console.log('1') setTimeout(function () { console.log('11') setTimeout(() => { console.log('11-1'); },100); setImmediate(() => { console.log('11-2') }) }, 0) setTimeout(function () { console.log('13') setTimeout(() => { console.log('15'); },10); setImmediate(() => { console.log('14') }) }, 300) setImmediate(() => console.log('12')); process.nextTick(() => console.log('7')); async1(); process.nextTick(() => console.log('8')); new Promise(function (resolve) { console.log('4') resolve(); console.log('5') }).then(function () { console.log('10') }) console.log('6') 总结:到此这篇关于node事件循环中事件执行的顺序的文章就介绍到这了,更多相关node 事件执行的顺序内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! |
请发表评论