Nodejs一些小得经验之谈

Nodejs一些小得经验之谈

一、setTimeout 在使用setTimout的时候需要注意下设置的时间,如果超过15分钟以上(这个值可能不准确),setTimeout会变成立即执行,所以长时间的定时器任务尽量使用setInterval来替代

二、多进程 多进程需要注意很多变量共享的问题 所有的全局变量都需要考虑变量共享问题 比如定义一个全局变量 timeout = setTimeout… 然后在另外一个地方调用了clearTimeout(timeout) 如果这两个执行都是异步的,那么有可能第一个调用在A进程中执行 而第二个变量可能在B进程中执行 那么B进程中并不会然后setTimeout中得函数终止

三、redis的一些小经验 1、setex 在setex之后如果在某个地方需要改变这个对应key的值或者改变key的名称 改变名称就用rename比较简单,rename不会清除过期时间 如果需要改变key值,一定需要先ttl读出具体的数值,然后重新调用setex重新设置 而不能通过set来直接改变,set之后过期时间会清除

2、zscan 有时候我们可能想到用zscan来做搜索 比如在一个zset里面查找某一个特定匹配的key 可能会这么写 zscan rank1 0 match abc* 然后就直接看返回值中是否存在对应的值 如果是想查找唯一,我感觉比较好的方式是加入count参数 zscan rank1 0 match abc* count 100000 原因: 如果不加count比较大得值,他会每次返回一个cursor的位置,然后你要不断的去检索,可能需要重复调用zscan很多次才能找到自己需要的值,或者导致错误

对于zscan的高级用法,如果有比较精通的人告知 我感觉用count得方式比较好,或许有更好的方式


7 回复

Node.js 一些小的经验之谈

一、setTimeout

在使用 setTimeout 的时候需要注意设置的时间。如果 setTimeout 的延时时间超过15分钟以上(这个值可能不准确),它可能会立即执行。因此,如果需要执行长时间的定时任务,建议使用 setInterval 来代替。

示例代码:

// 不推荐的方式
setTimeout(() => {
    console.log('This should be executed after 15 minutes');
}, 900000); // 15分钟

// 推荐的方式
const intervalId = setInterval(() => {
    console.log('This will execute every 15 minutes');
}, 900000); // 15分钟

// 如果需要停止定时器
clearInterval(intervalId);

二、多进程

在使用多进程时,需要注意全局变量的共享问题。由于每个进程都有独立的内存空间,全局变量在不同进程之间不会共享。因此,在处理异步操作时,确保这些操作在同一进程中执行。

示例代码:

let timeout; // 全局变量

// 在进程A中设置定时器
timeout = setTimeout(() => {
    console.log('定时器执行');
}, 3000);

// 在进程B中清除定时器
clearTimeout(timeout); // 这个操作可能不会按预期工作,因为它们可能在不同的进程中执行

为了避免这个问题,可以考虑使用消息传递机制(如 process.send()process.on('message'))来协调进程之间的操作。

示例代码:

// 进程A
const { fork } = require('child_process');

const child = fork('./childProcess.js');

child.send({ action: 'start', timeout: 3000 });

child.on('message', (msg) => {
    if (msg.action === 'stop') {
        console.log('定时器已停止');
    }
});

// 进程B
process.on('message', (msg) => {
    if (msg.action === 'start') {
        const timeout = setTimeout(() => {
            process.send({ action: 'execute' });
        }, msg.timeout);

        setTimeout(() => {
            process.send({ action: 'stop' });
            clearTimeout(timeout);
        }, msg.timeout / 2);
    }
});

三、Redis 的一些小经验

1. setex

在使用 setex 设置键值对并设置了过期时间后,如果需要更改键的值或键名,需要注意以下几点:

  • 使用 rename 更改键名不会影响过期时间。
  • 使用 set 更改键值会清除过期时间,因此需要重新设置过期时间。

示例代码:

const redis = require('redis');

const client = redis.createClient();

client.setex('rank1', 3600, 'value', (err) => {
    if (err) throw err;
});

// 更改键名
client.rename('rank1', 'rank2', (err) => {
    if (err) throw err;
});

// 更改键值
client.get('rank2', (err, reply) => {
    if (err) throw err;

    client.setex('rank2', 3600, reply + ' modified', (err) => {
        if (err) throw err;
    });
});
2. zscan

zscan 是一个强大的命令,用于在有序集合中进行分页查询。为了提高效率,可以在 zscan 中添加 count 参数,以减少重复调用的次数。

示例代码:

const redis = require('redis');

const client = redis.createClient();

client.zadd('rank1', 1, 'abc1');
client.zadd('rank1', 2, 'abc2');
client.zadd('rank1', 3, 'abc3');

client.zscan('rank1', 0, 'match', 'abc*', 'count', 100000, (err, reply) => {
    if (err) throw err;

    console.log(reply);
});

使用 count 参数可以一次性返回更多结果,从而减少查询次数,提高效率。


记录一下- -都是我没接触的东西- -。。。。。

我记得不是15分钟,而是这个数字2147483647,也就是int最大值,超过会变为负数,所以会立刻执行

多进程 变量不共享的把

你说的对,测试了下,谢谢

我是说需要去考虑做变量共享才行

Node.js 小经验之谈

一、setTimeout

在使用 setTimeout 的时候,需要注意设置的时间。如果设置的时间超过15分钟以上(这个值可能不准确),setTimeout 可能会变成立即执行。因此,如果需要长时间的定时任务,建议使用 setInterval 来替代。

示例代码:

// 使用 setTimeout
setTimeout(() => {
    console.log('This should be executed after 15 minutes');
}, 900000); // 15分钟

// 使用 setInterval
const intervalId = setInterval(() => {
    console.log('This will be executed every 15 minutes');
}, 900000); // 15分钟

二、多进程

在多进程中,需要注意全局变量的共享问题。每个进程都有自己独立的内存空间,因此全局变量在不同进程中可能不会同步。例如:

示例代码:

global.timeout = setTimeout(() => {
    console.log('This should be cleared');
}, 1000);

// 在另一个进程中
clearTimeout(global.timeout); // 这可能不会清除setTimeout

为了解决这个问题,可以使用进程间通信(IPC)机制。

三、Redis 的一些小经验

1. setex

使用 setex 设置键值对后,如果需要改变键的值或名称,应小心处理。修改键值需要先读取过期时间,然后再重新设置。

示例代码:

// 设置键值对
redisClient.setex('myKey', 3600, 'initialValue');

// 修改键值
redisClient.ttl('myKey', (err, ttl) => {
    if (err) throw err;
    redisClient.setex('myKey', ttl, 'newValue');
});
2. zscan

在使用 zscan 进行范围查询时,为了提高效率,可以使用 count 参数一次性返回更多结果。

示例代码:

redisClient.zscan('rank1', 0, 'MATCH', 'abc*', 'COUNT', 100000, (err, result) => {
    if (err) throw err;
    console.log(result);
});

如果不加 count 参数,可能会导致多次调用 zscan,增加不必要的网络开销。

希望这些经验对你有所帮助!

回到顶部