nodeJs事件循环运行代码怎么写

发布时间:2023-04-15 11:20:35 作者:iii
来源:亿速云 阅读:127

这篇文章主要讲解了“nodeJs事件循环运行代码怎么写”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“nodeJs事件循环运行代码怎么写”吧!

Nodejs运行时

JS语言是同步,阻塞,单线程的,但是nodejs不是。Nodejs由三个主要组件:

nodeJs事件循环运行代码怎么写

nodejs的异步特性主要由libuv提供。libuv是跨平台的使用c语言写的库,它主要提供对异步操作的支持。

node运行时代码运行

nodeJs事件循环运行代码怎么写

当我们在Nodejs中执行JS代码时,是由v8引擎处理代码执行,v8包括一块内存区域(堆)和调用栈。当定义函数,变量时,从堆中分配内存,当执行代码时将函数入栈,函数返回时出栈。

当执行异步操作时,libuv将接管该任务,然后使用操作系统的异步机制运行任务。如果缺乏系统级的异步机制,就使用线程池运行任务,保证主线程不被阻塞。

Event Loop

nodeJs事件循环运行代码怎么写

事件循环是一个nodejs应用运行后一直存在的循环。存在着六个不同的队列,每个都存储着不同的回调。

除了两个微任务队列,其他队列都是libuv自带的

如何工作?

同步代码优于异步代码,事件循环是call stack为空后开始。事件循环遵循的优先级规则:

需要注意的是在定时器队列,IO队列,check队列,close队列执行一个任务后都会检查并运行微任务队列。

实验

实验1

// index.js
console.log("console.log 1");
process.nextTick(() => console.log("this is process.nextTick 1"));
console.log("console.log 2");

输出

console.log 1
console.log 2
this is process.nextTick 1

结论: 同步先于异步

实验2

// index.js
Promise.resolve().then(() => console.log("this is Promise.resolve 1"));
process.nextTick(() => console.log("this is process.nextTick 1"));

输出

this is process.nextTick 1
this is Promise.resolve 1

结论: nextTick先于promise

实验3

// index.js
process.nextTick(() => console.log("this is process.nextTick 1"));
process.nextTick(() => {
  console.log("this is process.nextTick 2");
  process.nextTick(() =>
    console.log("this is the inner next tick inside next tick")
  );
});
process.nextTick(() => console.log("this is process.nextTick 3"));
Promise.resolve().then(() => console.log("this is Promise.resolve 1"));
Promise.resolve().then(() => {
  console.log("this is Promise.resolve 2");
  process.nextTick(() =>
    console.log("this is the inner next tick inside Promise then block")
  );
});
Promise.resolve().then(() => console.log("this is Promise.resolve 3"));

实验3

// index.js
process.nextTick(() => console.log("this is process.nextTick 1"));
process.nextTick(() => {
  console.log("this is process.nextTick 2");
  process.nextTick(() =>
    console.log("this is the inner next tick inside next tick")
  );
});
process.nextTick(() => console.log("this is process.nextTick 3"));
Promise.resolve().then(() => console.log("this is Promise.resolve 1"));
Promise.resolve().then(() => {
  console.log("this is Promise.resolve 2");
  process.nextTick(() =>
    console.log("this is the inner next tick inside Promise then block")
  );
});
Promise.resolve().then(() => console.log("this is Promise.resolve 3"));

输出

this is process.nextTick 1
this is process.nextTick 2
this is process.nextTick 3
this is the inner next tick inside next tick
this is Promise.resolve 1
this is Promise.resolve 2
this is Promise.resolve 3
this is the inner next tick inside Promise then block

解析:

nextTick内部增加的nextTick任务还是先于promise,因为nexttick队列清完后才会执行promise队列的任务。

promise里增加的nextTick任务晚于其他的promise,因为此时是在执行promise阶段,需要清空promise才会检查nextTick队列。

实验4

// index.js
setTimeout(() => console.log("this is setTimeout 1"), 0);
setTimeout(() => {
  console.log("this is setTimeout 2");
  process.nextTick(() =>
    console.log("this is inner nextTick inside setTimeout")
  );
}, 0);
setTimeout(() => console.log("this is setTimeout 3"), 0);
process.nextTick(() => console.log("this is process.nextTick 1"));
process.nextTick(() => {
  console.log("this is process.nextTick 2");
  process.nextTick(() =>
    console.log("this is the inner next tick inside next tick")
  );
});
process.nextTick(() => console.log("this is process.nextTick 3"));
Promise.resolve().then(() => console.log("this is Promise.resolve 1"));
Promise.resolve().then(() => {
  console.log("this is Promise.resolve 2");
  process.nextTick(() =>
    console.log("this is the inner next tick inside Promise then block")
  );
});
Promise.resolve().then(() => console.log("this is Promise.resolve 3"));

输出

this is process.nextTick 1
this is process.nextTick 2
this is process.nextTick 3
his is the inner next tick inside next tick
this is Promise.resolve 1
this is Promise.resolve 2
this is Promise.resolve 3
this is the inner next tick inside Promise then block
this is setTimeout 1
this is setTimeout 2
this is inner nextTick inside setTimeout
this is setTimeout 3

结论:

nextTick先于promise;微任务先于setTimeout;每个Timer任务后会检查执行微任务。

实验6

// index.js
setTimeout(() => console.log("this is setTimeout 1"), 1000);
setTimeout(() => console.log("this is setTimeout 2"), 500);
setTimeout(() => console.log("this is setTimeout 3"), 0);

输出

this is setTimeout 3
this is setTimeout 2
this is setTimeout 1

结论: Timer队列是按时间排序的

实验7

// index.js
const fs = require("fs");
fs.readFile(__filename, () => {
  console.log("this is readFile 1");
});
process.nextTick(() => console.log("this is process.nextTick 1"));
Promise.resolve().then(() => console.log("this is Promise.resolve 1"));

输出

this is process.nextTick 1
this is Promise.resolve 1

结论:微任务先于io任务

实验8

// index.js
const fs = require("fs");
setTimeout(() => console.log("this is setTimeout 1"), 0);
fs.readFile(__filename, () => {
  console.log("this is readFile 1");
});

输出

不确定

解析:setTimeout 0通常内部会取1ms,也就是1ms后执行Timer任务,而cpu进入事件循环的时机不定,所以有可能进入事件循环时已经过了1ms,那么先执行timer任务,也可能进入时定时任务没到时间,会先执行IO任务。

实验9

// index.js
const fs = require("fs");
fs.readFile(__filename, () => {
  console.log("this is readFile 1");
});
process.nextTick(() => console.log("this is process.nextTick 1"));
Promise.resolve().then(() => console.log("this is Promise.resolve 1"));
setTimeout(() => console.log("this is setTimeout 1"), 0);
for (let i = 0; i < 2000000000; i++) {}

输出

this is process.nextTick 1
this is Promise.resolve 1
this is setTimeout 1
this is readFile 1

解析:

代码最后加了循环保证进入事件循环时定时器任务已经到期,所以先执行Timer任务

实验10

// index.js
const fs = require("fs");
fs.readFile(__filename, () => {
  console.log("this is readFile 1");
});
process.nextTick(() => console.log("this is process.nextTick 1"));
Promise.resolve().then(() => console.log("this is Promise.resolve 1"));
setTimeout(() => console.log("this is setTimeout 1"), 0);
setImmediate(() => console.log("this is setImmediate 1"));
for (let i = 0; i < 2000000000; i++) {}

输出

this is process.nextTick 1
this is Promise.resolve 1
this is setTimeout 1
this is setImmediate 1
this is readFile 1

解析: 按理说IO任务先于check任务,但是第一次事件循环时IO任务的callback并不在队列里。在两个队列之间会通过IO polling的方式去查看io任务是否完成,完成了就将callback加到队列里,然后下一轮循环时会调用

感谢各位的阅读,以上就是“nodeJs事件循环运行代码怎么写”的内容了,经过本文的学习后,相信大家对nodeJs事件循环运行代码怎么写这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

推荐阅读:
  1. 怎么使用nodejs代码在SAP C4C里创建Individual customer
  2. Holer怎么实现外网访问内网NodeJS

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

nodejs

上一篇:Mysql报错Duplicate entry '值' for key '字段名'如何解决

下一篇:kotlin中::双冒号如何使用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》