首页 > 编程语言 >nodejs学习

nodejs学习

时间:2024-09-29 21:00:32浏览次数:8  
标签:console log nodejs data 学习 let const type

nodejs中的v8引擎模块

一、promise钩子模块;
二、垃圾回收模块;

1、promise钩子包括:
(1)onInit(callback) 在promise创建时调用;
(2)onSettled(callback) 在fulfilled或rejected时调用;
(3)onBefore(callback) 在promise继续执行之前调用的回调;
(4)onAfter(callback) 在promise继续执行之后调用的回调;

const { promiseHooks } = require('v8')

// 1、创建一个钩子函数,在Promise对象初始化时输出日志;
const initHook = () => {
    console.log('Promise 对象被创建')
}
// 注册钩子函数
promiseHooks.onInit(initHook)

// 2、定义一个settle钩子函数
const settledHook = () => {
    console.log('当promise对象被settled(即fulfilled或rejected)时触发;')
}

// 注册钩子函数
promiseHooks.onSettled(settledHook)

// 3、定义一个before钩子函数
const beforeHook = () => {
    console.log('Promise 对象 在 promise 继续执行之前调用的回调;')
}

promiseHooks.onBefore(beforeHook)

// 4、定义一个before钩子函数
const afterHook = () => {
    console.log('Promise 对象 在 promise 继续执行后调用的回调;')
}

promiseHooks.onAfter(afterHook)

let promiseObj = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('Promise resolved')
    }, 2000);
})

promiseObj.then((result) => {
    console.log(result)
})

运行的结果:

2、v8的垃圾回收
垃圾回收包括3种回收算法:
(1)引用计数法:js维护的引用表记录了内存的引用次数,当值为0时,被GC回收,它虽然能在发现垃圾时及时清除,但无法处理循环引用的对象内存;
(2)标记清除法:遍历当前对象是否可以访问,如果不能则添加标记然后清除,它遍历的均为可达对象而不是像循环引用的局部对象,因此可以解决循环引用问题,但其标记和清除是在不同阶段执行的,不能立即清除;
(3)分代算法:堆内存中存在新生代和老生代2种空间,在新生代,新创建的对象都会被分配到from区域,在GC阶段,将from区域中存活的数据复制到2区域,2区域再进行交互,实现一次垃圾回收,如果在两次gc中都还存活的数据就会被晋升到老生代区域存储。

const v8 = require('v8')

// 启用GCprofile
v8.setFlagsFromString('--trace_gc');

// 模拟创建大量对象并释放内存
const createObject = () => {
    const object = []
    for (let i = 0; i < 100000; i++) {
        object.push({})
    }
}
createObject()

// 等待一段时间,让垃圾回收产生
setTimeout(() => {
    v8.setFlagsFromString('--notrace_gc')
}, 5000);

运行的结果:

nodejs中EventEmitter
1、EventEmitter实现

// 自己实现一个eventEmitter

/**
 * 1、注册
 * 2、触发
 * 3、移除
 * 4、测试
 */

class EventEmitter {
    constructor() {
        this._event = {}
    }

    // 注册
    on (type, listener) {
        let events = this._event
        let existing = events[type]
        if (existing === undefined) {
            events[type] = [listener]
        } else {
            // 事件存在则追加
            events[type] = [...existing, listener]
        }
        return this
    }
    // 触发
    emit (type, ...args) {
        // 找到当前触发的回调函数
        const handler = this._event[type]
        console.log('handler', handler)
        if (!handler) {
            console.log(`event ${type} noting existing!`)
        } else {
            // 存在当前事件
            const length = handler.length
            // 当前事件只有一个
            if (length === 1) {
                // 直接触发回调函数
                handler[0](args)
            } else if (length > 1) {
                // 当前事件有多个回调函数
                // 遍历该事件所有回调函数,依次触发
                for (let i = 0; i < length; i++) {
                    handler[i](args)
                }
            } else {
                return this
            }
        }
    }
    // 移除监听
    off (type, listener) {
        let list = this._event[type]
        if (!list) {
            // 事件不存在
            console.log(`event ${type} is not existing!`)
        } else {
            let length = list.length
            let postion
            if (length === 1) {
                delete this._event[type]
            } else {
                // 要删除的事件存在多个监听
                // 找出要删除的事件的下标
                for (let i = 0; i < length; i++) {
                    if (list[i] + '' === listener + '') {
                        postion = i
                        break
                    } else {
                        postion = -1
                    }
                }
                if (postion != -1) {
                    delete this._event[type].splice(postion, 1)
                } else {
                    this._event[type].pop()
                }
            }
        }
    }
}

let emitter = new EventEmitter()
emitter.on('data', (data) => {
    console.log('第一个订阅data事件的对象:', data)
})

let handler = (data) => {
    console.log('第二个订阅data事件的对象', data)
}
emitter.on('data', handler)

emitter.on('data', (data) => {
    console.log('第三个订阅data事件的对象', data)
})

emitter.off('data', handler)
emitter.emit('data', 'hello world')

运行结果

node事件循环
尽管js是单线程的,但是可以通过将异步操作转移到系统内核去完成从而实现非阻塞的机制称为事件循环。
因为现代内核都是多线程的,它们可以在后台执行多个操作,当某个操作完成时,内核通知Node.js,将对应的回调添加到轮询队列中。

事件循环的六个阶段:
1、timer阶段,执行setTimeout()和setInterval()
2、Pending和callbacks阶段:执行推迟到下一个循环迭代的I/O回调。
3、idle、prepare阶段,内部使用
4、poll阶段:执行I/O操作
5、check阶段:执行setImmediate()
6、close callbacks阶段:关闭回调
在每次运行事件循环时,Node.js都会检查它是否在等待任何异步I/O或定时器,如果没有,则会关闭。

使用process.nextTick的原因:
1、允许用户处理错误,清除任何不需要的资源,或者在事件循环继续之前重试请求
2、允许回调在同步之后,但在事件循环之前运行

标签:console,log,nodejs,data,学习,let,const,type
From: https://www.cnblogs.com/elian/p/18437002

相关文章

  • 独家发布:全面大模型LLM学习路线图揭晓!非常详细收藏我这一篇就好了!
    ChatGPT的出现在全球掀起了AI大模型的浪潮,2023年可以被称为AI元年,AI大模型以一种野蛮的方式,闯入你我的生活之中。从问答对话到辅助编程,从图画解析到自主创作,AI所展现出来的能力,超出了多数人的预料,让不少人惊呼:“未来是属于AI的”。AI大模型——成为互联网从业者必备技能。......
  • 大语言模型实战学习路径:从基础到精通,从入门到精通非常详细
    大语言模型学习路线:从入门到实战在人工智能领域,大语言模型(LargeLanguageModels,LLMs)正迅速成为一个热点话题。本学习路线旨在为有基本Python编程和深度学习基础的学习者提供一个清晰、系统的大模型学习指南,帮助你在这一领域快速成长。本学习路线更新至2024年02月,后期......
  • Java中流的学习
    流的基本概念目录流的基本概念一、流的基本概念二、流的分类三、流的使用场景四、流的特性Java中关于流(Stream)的知识是一个广泛而深入的主题,它涵盖了Java标准库中用于处理输入输出(IO)的多种抽象和类。以下是对Java流知识的详细归纳:一、流的基本概念定义:Java流是Java标准库中......
  • 生信机器学习入门4 - 构建决策树(Decision Tree)和随机森林(Random Forest)分类器
    机器学习文章回顾生信机器学习入门1-数据预处理与线性回归(Linearregression)预测生信机器学习入门2-机器学习基本概念生信机器学习入门3-Scikit-Learn训练机器学习分类感知器生信机器学习入门4-scikit-learn训练逻辑回归(LR)模型和支持向量机(SVM)模型1.决策树(Dec......
  • 2024-2025-1 20241318 《计算机基础与程序设计》第一周学习总结
    这个作业属于哪个课程<班级的链接>(如2024-2025-1-计算机基础与程序设计)这个作业要求在哪里<作业要求的链接>(如2024-2025-1计算机基础与程序设计第一周作业)这个作业的目标阅读浏览教材《计算机科学概论》并提出自己的问题,基于AI进行学习作业正文...本博客链接......
  • 学年(2024-2025-1) 学号(20241424)《计算机基础与程序设计》第一周学习总结
    学年(2024-2025)学号(20241424)《计算机基础与程序设计》第一周学习总结作业信息|这个作业属于2024-2025-1-计算机基础与程序设计)||-- |-- ||这个作业要求在2024-2025-1计算机基础与程序设计第一周作业)||这个作业的目标|<参考上面的学习总结模板,把学习过程通过博客(随笔)发表,博......
  • prometheus学习笔记之alertmanager告警配置
    一、安装alertmanager项目地址:https://github.com/prometheus/alertmanager帮助文档:https://prometheus.io/docs/alerting/latest/alertmanager/配置文档:https://prometheus.io/docs/alerting/latest/configuration/wgethttps://github.com/prometheus/alertmanager/releas......
  • 嵌入式开发学习日记——第五天(c语言)
    循环控制语句 while循环        基本语法while(循环条件表达式){循环体语句;}        流程图案例——计数循环   实现计数循环要满足:        ①必须初始化循环变量        ②循环变量比较作为循环条件       ......
  • 2024-2025-1 20241327 《计算机基础与1程序设计》第1周学习总结
    作业信息|2024-2025-1-计算机基础与程序设计)||-- |-|2024-2025-1计算机基础与程序设计第一周作业)||快速浏览一遍教材计算机科学概论(第七版),课本每章提出至少一个自己不懂的或最想解决的问题并在期末回答这些问题|作业正文|...本博客链接 |教材学习内容总结-《计算机科学概......
  • Pytorch学习笔记--搭建神经网络以及Sequential的使用
    首先,搭建一个如下图所示的神经网络: 分析图片,inputs输入图片的inchannels=3,尺寸是32*32,经过kernel_size=5的卷积操作后out_channels=32,尺寸32*32,套用下方公式可算出padding=2(默认dilation=1,stride=1):self.conv1=Conv2d(3,32,5,padding=2)  之后再进行池化操作Max-poolin......