前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nodejs中事件循环中的执行顺序

nodejs中事件循环中的执行顺序

作者头像
蓓蕾心晴
发布2022-11-21 09:19:09
1.8K0
发布2022-11-21 09:19:09
举报
文章被收录于专栏:前端小叙

nodejs 事件循环是一个典型的生产者/消费者模型,异步 I/O、网络请求等是事件的生产者,源源不断为 Node 提供不同类型的事件,这些事件被传递到对应的观察者那里,事件循环则从观察者那里取出事件并处理。

事件循环、观察者、请求对象、I/O 线程池共同构成了 Node 异步 I/O 模型的基本要素。

Node 异步 I/O 几个关键词:单线程、事件循环、观察者、I/O 线程池,JavaScript 是单线程,node自身是多线程,只是 I/O 线程使用的 CPU 较少。除了用户代码无法并行执行外,所有的 I/O(磁盘 I/O 和网络 I/O 等)是可以并行起来的。

node 中还存在一些与 I/O 无关的异步 API,setTimeout()、setInteval()、setImmediate()、process.nextTick()

process.nextTick()=> idle 观察者

setImmediate() => check 观察者

事件循环对观察者的检查有先后顺序,idle观察者先于 I/O 观察者,I/O 观察者先于 check 观察者。

代码语言:javascript
复制
const fs = require("fs");
const path = require("path");

const wait = () =>
    new Promise((resolove, reject) => {
        setTimeout(resolove(true), 3);
    });
fs.readFile(
    path.resolve(__dirname, "./limit.js"),
    "utf-8",
    async (err, data) => {
        console.log("读取的文件内容1");
    }
);
fs.readFile(
    path.resolve(__dirname, "./limit.js"),
    "utf-8",
    async (err, data) => {
        console.log("读取的文件内容2");
        await wait();
        console.log("读取文件内容2,等待3 秒后输出");
        process.nextTick(() => {
            console.log("读取文件内容2,等待3 秒后执行 process.nextTick");
        });
    }
);

console.log("start");

setTimeout(function () {
    console.log("setTimeout-1");
    process.nextTick(function () {
        console.log("setTimeout-1-process.nextTick");
    });
    new Promise(function (resolve) {
        console.log("setTimeout-1-Promise");
        resolve();
    }).then(function () {
        console.log("setTimeout-1-Promise-then");
    });
});
setImmediate(() => {
    console.log("setImmediate-1");
    process.nextTick(function () {
        console.log("setImmediate-1-process.nextTick-1");
    });
});
setImmediate(() => {
    console.log("setImmediate-2");
});
process.nextTick(function () {
    console.log("process.nextTick-1");
});
process.nextTick(function () {
    console.log("process.nextTick-2");
});
new Promise(function (resolve) {
    console.log("Promise-1");
    resolve();
}).then(function () {
    console.log("Promise-1-then");
});

setTimeout(function () {
    console.log("setTimeout-2");
    process.nextTick(function () {
        console.log("setTimeout-2-process.nextTick");
    });
    new Promise(function (resolve) {
        console.log("setTimeout-2-Promise");
        resolve();
    }).then(function () {
        console.log("setTimeout-2-Promise-then");
    });
});
// 执行结果
// start
// Promise-1

// 在每轮循环中,会将 process.nextTick 全部执行完,优先级> promise.then
// process.nextTick-1
// process.nextTick-2
// Promise-1-then

// setTimeout timer 优先级> setImmediate check 观察者
// setTimeout-1
// setTimeout-1-Promise
// setTimeout-1-process.nextTick
// setTimeout-1-Promise-then

// setTimeout-2
// setTimeout-2-Promise
// setTimeout-2-process.nextTick
// setTimeout-2-Promise-then

// 一次循环只执行一个 setImmediate
// setImmediate-1
// setImmediate-1-process.nextTick-1
// setImmediate-2

// 读取的文件内容1
// 读取的文件内容2
// 读取文件内容2,等待3 秒后输出
// 读取文件内容2,等待3 秒后执行 process.nextTick
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-11-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档