29 # node 中的 eventloop

简介: 29 # node 中的 eventloop

process.cwd

cwd:current working directory 表示当前用户的工作目录(这个目录可以更改用户自己切换即可)

当用户在哪执行 node 命令,就去哪找配置文件

console.log(process.cwd());

__dirname:表示当前文件所在的目录,这个目录是不能手动修改的,它不是 global 上的属性,是每个模块都会传入的属性

process.env

env:环境变量,可以根据环境变量实现不同的功能,比如:

let domain = process.env.NODE_ENV === "production" ? "localhost" : "https://blog.csdn.net/kaimo313";

设置临时的环境变量:

  • windows:set key=value
  • mac:export key=value

我的系统是 windows 的,下面我用 set key=value 试一下

先在 cmd 里设置临时的环境变量,set kaimo=313,然后执行 node env.js,输出是有 313 的值

set kaimo=313

然后你打开 powershell 执行 node env.js 是没有这个值输出

console.log(process.env.kaimo);

node 中的 eventloop

事件循环是 Node.js 处理非阻塞 I/O 操作的机制。

现在浏览器的事件环跟 node 的事件环执行效果是一样的(node 10 版本后)

详细的可以查看文档:https://nodejs.org/zh-cn/docs/guides/event-loop-timers-and-nexttick

事件循环操作顺序的简化概览图:

从上至下执行分成下面这些阶段,每个框被称为事件循环机制的一个阶段,这些阶段都是一个队列。

  • 定时器(timers):此阶段执行由 setTimeout()setInterval() 排序。
  • 挂起的回调函数(pending callbacks):执行 I/O 回调推迟到下一个循环迭代。【内部机制】
  • idle, prepare:仅在内部使用。【内部机制】
  • 轮询(poll):检索新的 I/O 事件; 执行与 I/O 相关的几乎任何回调(由“计时器”或 “setImmediate()”所设的紧邻回调除外); node 将在适当时机在此处暂停。
  • 检查阶段(check):setImmediate() 回调在此处被调用。
  • 关闭的回调函数(close callbacks):一些关闭的回调函数,如:socket.on('close', ...)

setImmediate vs setTimeout

  • setImmediate() 实际上是一个在事件循环的单独阶段运行的特殊计时器。它使用一个 libuv API 来安排回调在轮询阶段完成后执行。。
  • setTimeout() 在已过期的最小阈值后运行。
setTimeout(() => {
    console.log("setTimeout");
}, 0);
setImmediate(() => {
    console.log("setImmediate");
});

上面代码有时先输出 setTimeout,然后输出 setImmediate,有时先输出 setImmediate,再输出 setTimeout。

按照上面的概览图,应该先走 timers 再到 check 阶段,先输出 setTimeout,然后输出 setImmediate,那为什么会出现有时反过来的情形?

这是因为如果运行不在 I/O 周期(即主模块)内的脚本,则执行两个计时器的顺序是非确定性的,因为它受进程性能的约束。进入事件环时 setTimeout 有可能没有完成。

我们可以试试放在 I/O 周期 里:

// poll -> check -> timers
const fs = require("fs");
fs.readFile("./file/name.txt", "utf-8", (err, data) => {
    if (err) throw err;
    console.log(data);
    setTimeout(() => {
        console.log("setTimeout");
    }, 0);
    setImmediate(() => {
        console.log("setImmediate");
    });
});

这个顺序就是一个确定的 poll -> check -> timers

process.nextTick

node 中自己实现的微任务 process.nextTick / queueMicrotask,宏任务 setImmediate

setTimeout(() => {
    console.log(2);
});
process.nextTick(() => {
    console.log(1);
});
queueMicrotask(() => {
    console.log(3);
});
// 输出 1 3 2

process.nextTick 并不属于事件环的一部分,在本轮代码执行后执行(timers 到 poll 为一轮,如果后有 check 就执行 check )

// nextTick 比 Promise 的 then 要快一些
setTimeout(() => {
    console.log(1);
    Promise.resolve().then(() => {
        console.log("then");
    });
    process.nextTick(() => {
        console.log("nextTick");
    });
}, 0);
setTimeout(() => {
    console.log(2);
}, 0);

目录
相关文章
|
存储 缓存 监控
Flink内存管理机制及其参数调优
Flink内存管理机制及其参数调优
|
缓存 Ubuntu Linux
docker的安装和常用命令
最近学习了docker做了一些笔记,跟朋友们分享一下
867 0
|
存储 设计模式 API
设计模式 | 工厂(方法)模式
工厂模式是简单工厂模式的延伸,它继承了简单工厂模式的优点,同时还弥补了简单工厂模式的不足。工厂方法模式是使用频率最高的设计模式之一,是很多开源框架和 API 类库的核心模式。
154 1
设计模式 | 工厂(方法)模式
|
人工智能 安全 大数据
谢钧棋:以“数”转型 用“脉”管理 | 阿里CIO学院名人堂
8月20日-21日,蒂脉科技创始人谢钧棋董事长(花名:科技皇后)作为中国中小企业协会金融科技分会的学员代表,受邀参加了由阿里CIO学院举办32期走进阿里活动,为期两天的交流使她深切直观地学习了阿里巴巴集团的企业文化与价值观,了解了阿里有关数字化转型的理念和最佳实践。
4233 0
谢钧棋:以“数”转型 用“脉”管理 | 阿里CIO学院名人堂
UIView之userInteractionEnabled属性介绍
来源:http://my.oschina.net/hmj/blog/108002 属性作用        该属性值为布尔类型,如属性本身的名称所释,该属性决定UIView是否接受并响应用户的交互。
743 0
|
3天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!