使用ioredis在Node.js中操作Redis数据结构的详细指南

使用ioredis在Node.js中操作Redis数据结构的详细指南

一. 使用ioredis操作Redis数据结构的详细知识点讲解

在Node.js中,ioredis是一个强大且易于使用的Redis客户端库,它提供了对Redis数据库的直接操作。本文将通过一系列代码示例,详细解释如何使用ioredis进行基本的Redis操作,适合初学者理解和学习。

1. 连接管理

首先,我们需要连接到Redis服务器。ioredis默认连接到本地的localhost:6379

javascript 复制代码
const Redis = require('ioredis');
const redis = new Redis(); // 默认连接到 localhost:6379

// 连接到Redis
redis.on('connect', () => {
  console.log('Connected to Redis');
});

// 断开与Redis的连接
redis.disconnect().then(() => {
  console.log('Disconnected from Redis');
});

2. 字符串操作

使用ioredis操作Redis中的字符串类型的详细知识点如下:

1) 基本字符串操作

设置键值对

使用set方法设置键值对:

javascript 复制代码
redis.set('key', 'value');

获取键值对

使用get方法获取键值对的值:

javascript 复制代码
redis.get('key', (err, result) => {
  if (err) throw err;
  console.log(result); // 输出: value
});

设置键值对并设置过期时间

使用setex方法设置键值对,并指定过期时间(秒):

javascript 复制代码
redis.setex('key', 10, 'value');
2) 字符串的过期和删除

删除键

使用del方法删除键:

javascript 复制代码
redis.del('key');
3). 字符串的过期时间

设置键的过期时间

使用expire方法设置键的过期时间(秒):

javascript 复制代码
redis.expire('key', 60);

查看键的剩余过期时间

使用ttl方法查看键的剩余过期时间(秒):

javascript 复制代码
redis.ttl('key');
5). 字符串的位操作

ioredis也支持对字符串执行位操作,例如:

javascript 复制代码
redis.getbit('key', 0); // 获取位
redis.setbit('key', 0, 1); // 设置位
6). 管道和事务

ioredis支持管道和事务,可以批量执行命令,提高性能:

javascript 复制代码
redis.pipeline()
  .set('foo', 'bar')
  .get('foo')
  .exec((err, results) => {
    // results === [ [null, 'OK'], [null, 'bar'] ]
  });

以上是使用ioredis操作Redis中字符串类型的一些基本和高级操作。通过这些操作,你可以有效地管理Redis中的字符串数据。

3. 哈希操作

使用ioredis操作Redis中的哈希(Hash)数据结构时,你可以执行多种操作来管理这些复杂的数据结构。以下是一些详细的知识点和操作方法:

1). 设置哈希字段的值
  • hset(key, field, value):为哈希表中的指定字段赋值。

    javascript 复制代码
    redis.hset('myhash', 'field1', 'value1');
2). 获取哈希字段的值
  • hget(key, field) :获取哈希表中指定字段的值。

    javascript 复制代码
    redis.hget('myhash', 'field1').then((value) => {
      console.log('Value:', value); // 输出 'value1'
    });
3). 批量设置哈希字段的值
  • hmset(key, field1, value1, field2, value2, ...) :同时设置哈希表中的多个字段的值。

    javascript 复制代码
    redis.hmset('myhash', 'field2', 'value2', 'field3', 'value3');
4). 批量获取哈希字段的值
  • hmget(key, field1, field2, ...) :同时获取哈希表中多个字段的值。

    javascript 复制代码
    redis.hmget('myhash', 'field1', 'field2', 'field3').then((values) => {
      console.log(values); // 输出 ['value1', 'value2', 'value3']
    });
5). 获取哈希表中的字段数量
  • hlen(key) :获取哈希表中字段的数量。

    javascript 复制代码
    redis.hlen('myhash').then((result) => {
      console.log(result); // 输出字段数量
    });
6). 删除哈希字段
  • hdel(key, field) :删除哈希表中的一个或多个字段。

    javascript 复制代码
    redis.hdel('myhash', 'field1').then((result) => {
      console.log(result); // 输出被删除的字段数量
    });
7). 获取哈希表中的所有字段名
  • hkeys(key) :获取哈希表中的所有字段名。

    javascript 复制代码
    redis.hkeys('myhash').then((fields) => {
      console.log(fields); // 输出所有字段名
    });
8). 获取哈希表中的所有值
  • hvals(key) :获取哈希表中的所有值。

    javascript 复制代码
    redis.hvals('myhash').then((values) => {
      console.log(values); // 输出所有值
    });
9). 获取哈希表中的所有字段和值
  • hgetall(key) :获取哈希表中的所有字段和值。

    javascript 复制代码
    redis.hgetall('myhash').then((hash) => {
      console.log(hash); // 输出所有字段和值
    });
10). 检查哈希字段是否存在
  • hexists(key, field) :检查哈希表中指定的字段是否存在。

    javascript 复制代码
    redis.hexists('myhash', 'field1').then((exists) => {
      console.log(exists); // 如果字段存在,输出 1,否则输出 0
    });
11). 为哈希表字段的整数值增加增量
  • hincrby(key, field, increment) :为哈希表中指定字段的整数值增加指定的增量。

    javascript 复制代码
    redis.hincrby('myhash', 'field1', 1); // 将 'field1' 的值增加 1
12). 为哈希表字段的浮点数值增加增量
  • hincrbyfloat(key, field, increment) :为哈希表中指定字段的浮点数值增加指定的增量。

    javascript 复制代码
    redis.hincrbyfloat('myhash', 'field1', 1.5); // 将 'field1' 的值增加 1.5
13). 获取哈希表中字符串字段的长度
  • hstrlen(key, field) :获取哈希表中字符串字段的长度。

    javascript 复制代码
    redis.hstrlen('myhash', 'field1').then((length) => {
      console.log(length); // 输出字段值的长度
    });

这些操作提供了对Redis哈希数据结构的全面管理能力,使得在Node.js应用中处理复杂数据变得更加简单和高效。

4. 列表操作

使用ioredis操作Redis中的列表(List)数据结构时,你可以执行多种操作来管理这些数据结构。以下是一些详细的知识点和操作方法:

1). 插入元素
  • lpush(key, ...values):在列表的左侧(头部)插入一个或多个元素。

    javascript 复制代码
    await redis.lpush('my_list', 'element1', 'element2');

    参考:腾讯云开发者社区-使用aioredis操作列表对象:插入单个元素

  • rpush(key, ...values):在列表的右侧(尾部)插入一个或多个元素。

    javascript 复制代码
    await redis.rpush('my_list', 'element1', 'element2');
2). 弹出元素
  • lpop(key):从列表的左侧(头部)弹出一个元素。

    javascript 复制代码
    const element = await redis.lpop('my_list');
  • rpop(key):从列表的右侧(尾部)弹出一个元素。

    javascript 复制代码
    const element = await redis.rpop('my_list');
3). 获取列表长度
  • llen(key) :获取列表的长度。

    javascript 复制代码
    const length = await redis.llen('my_list');
4). 获取列表元素
  • lrange(key, start, stop) :获取列表中指定范围内的元素。

    javascript 复制代码
    const elements = await redis.lrange('my_list', 0, -1); // 获取所有元素
5). 删除元素
  • lrem(key, count, value) :删除列表中与给定值相等的元素。

    javascript 复制代码
    // 从列表中删除第一个匹配的元素
    await redis.lrem('my_list', 1, 'element1');
6). 根据索引设置元素值
  • lset(key, index, value) :设置列表指定索引处的元素值。

    javascript 复制代码
    await redis.lset('my_list', 0, 'newElement');
7). 截取列表
  • ltrim(key, start, stop) :对一个列表进行修剪,只保留指定范围内的元素。

    javascript 复制代码
    await redis.ltrim('my_list', 0, -1); // 保留所有元素
8). 管道和事务

ioredis支持管道和事务,可以批量执行命令,提高性能:

javascript 复制代码
const pipeline = redis.pipeline();
pipeline.lpush('my_list', 'newElement');
pipeline.lrange('my_list', 0, -1);
pipeline.exec((err, results) => {
  // 处理结果
});

以上是使用ioredis操作Redis中列表数据结构的一些基本和高级操作。通过这些操作,你可以有效地管理Redis中的列表数据。

5. 集合操作

使用ioredis操作Redis中的集合(Set)数据结构时,你可以执行多种操作来管理这些数据结构。以下是一些详细的知识点和操作方法:

1). 向集合添加元素
  • sadd(key, member1, member2, ...) :向集合中添加一个或多个元素。如果元素已存在,则不会重复添加。

    javascript 复制代码
    await redis.sadd('myset', 'one', 'two', 'three');
2). 从集合中移除元素
  • srem(key, member1, member2, ...) :从集合中移除一个或多个元素。

    javascript 复制代码
    await redis.srem('myset', 'two');
3). 检查元素是否在集合中
  • sismember(key, member) :检查元素是否是集合的成员。

    javascript 复制代码
    const isMember = await redis.sismember('myset', 'one');
    console.log('Is member:', isMember); // true 或 false
4). 获取集合中的所有元素
  • smembers(key) :获取集合中的所有元素。

    javascript 复制代码
    const members = await redis.smembers('myset');
    console.log('Members:', members);
5). 获取集合的大小
  • scard(key) :获取集合的大小,即元素的数量。

    javascript 复制代码
    const size = await redis.scard('myset');
    console.log('Set size:', size);
6). 集合运算
  • sinter(key1, key2, ...):返回两个或多个集合的交集。

    javascript 复制代码
    const intersection = await redis.sinter('myset', 'anotherSet');
    console.log('Intersection:', intersection);
  • sunion(key1, key2, ...):返回两个或多个集合的并集。

    javascript 复制代码
    const union = await redis.sunion('myset', 'anotherSet');
    console.log('Union:', union);
  • sdiff(key1, key2, ...):返回两个集合的差集,即存在于第一个集合中但不在第二个集合中的元素。

    javascript 复制代码
    const difference = await redis.sdiff('myset', 'anotherSet');
    console.log('Difference:', difference);
  • smove(source, destination, member):将元素从一个集合移动到另一个集合。

    javascript 复制代码
    await redis.smove('myset', 'anotherSet', 'one');

以上是使用ioredis操作Redis中集合数据结构的一些基本操作。通过这些操作,你可以有效地管理Redis中的集合数据。

6. 有序集合操作

使用ioredis操作Redis中的有序集合(Sorted Set)涉及到一系列的命令,这些命令可以帮助你管理有序集合中的数据。以下是一些详细的知识点和操作方法:

1). 向有序集合添加元素
  • zadd(key, score, member) :向有序集合中添加一个元素,或者更新已存在元素的分数。

    javascript 复制代码
    await redis.zadd('myzset', { 'one': 1, 'two': 2, 'three': 3 });
2). 获取有序集合中的元素
  • zrange(key, start, stop, withscores) :获取有序集合中指定范围内的元素,可以包含分数。

    javascript 复制代码
    const elements = await redis.zrange('myzset', 0, -1, 'WITHSCORES');
    console.log(elements); // 输出 ['one', '1', 'two', '2', 'three', '3']
3). 获取有序集合中元素的逆序排列
  • zrevrange(key, start, stop, withscores) :获取有序集合中指定范围内的元素,按照分数从大到小排序。

    javascript 复制代码
    const elements = await redis.zrevrange('myzset', 0, -1, 'WITHSCORES');
    console.log(elements); // 输出 ['three', '3', 'two', '2', 'one', '1']
4). 获取有序集合中元素的排名
  • zrank(key, member):获取有序集合中指定元素的排名,按分数从小到大排列。

    javascript 复制代码
    const rank = await redis.zrank('myzset', 'two');
    console.log(rank); // 输出 '1'
  • zrevrank(key, member):获取有序集合中指定元素的排名,按分数从大到小排列。

    javascript 复制代码
    const rank = await redis.zrevrank('myzset', 'two');
    console.log(rank); // 输出 '2'
5). 删除有序集合中的元素
  • zrem(key, member1, member2, ...) :从有序集合中移除一个或多个元素。

    javascript 复制代码
    await redis.zrem('myzset', 'one');
6). 获取有序集合的大小
  • zcard(key) :获取有序集合中的成员数。

    javascript 复制代码
    const size = await redis.zcard('myzset');
    console.log(size); // 输出集合的大小
7). 计算有序集合中指定分数区间的成员数
  • zcount(key, min, max) :计算在有序集合中指定区间分数的成员数。

    javascript 复制代码
    const count = await redis.zcount('myzset', '1', '2');
    console.log(count); // 输出分数在1到2之间的成员数
8). 增加有序集合中元素的分数
  • zincrby(key, increment, member) :有序集合中对指定成员的分数加上增量。

    javascript 复制代码
    await redis.zincrby('myzset', 1, 'two'); // 将 'two' 的分数增加 1
9). 获取有序集合中元素的分数
  • zscore(key, member) :获取有序集合中指定成员的分数。

    javascript 复制代码
    const score = await redis.zscore('myzset', 'two');
    console.log(score); // 输出 'two' 的分数
10). 根据分数区间获取有序集合中的元素
  • zrangebyscore(key, min, max, withscores, limit) :返回有序集合中指定分数区间的成员。

    javascript 复制代码
    const elements = await redis.zrangebyscore('myzset', '1', '3', 'WITHSCORES');
    console.log(elements); // 输出分数在1到3之间的成员及其分数
11). 根据字典区间获取有序集合中的元素
  • zrangebylex(key, min, max) :通过字典区间返回有序集合的成员。

    javascript 复制代码
    const elements = await redis.zrangebylex('myzset', '-', '+');
    console.log(elements); // 输出字典序在 '-' 到 '+' 之间的成员
12). 移除有序集合中指定分数区间的成员
  • zremrangebyscore(key, min, max) :移除有序集合中给定的分数区间的所有成员。

    javascript 复制代码
    await redis.zremrangebyscore('myzset', '1', '2');

以上是使用ioredis操作Redis中有序集合的一些基本和高级操作。通过这些操作,你可以有效地管理Redis中的有序集合数据。

7. 发布/订阅

发布/订阅模式允许我们发布消息到频道,并订阅频道以接收消息。

javascript 复制代码
// 向频道发布消息
redis.publish('myChannel', 'Hello!').then((numSubscribers) => {
  console.log('Number of subscribers:', numSubscribers);
});

// 订阅频道
const subscriber = new Redis();
subscriber.on('message', (channel, message) => {
  console.log(`Received data: ${message} from ${channel}`);
});
subscriber.subscribe('myChannel');

8. 键管理

键管理操作允许我们检查键是否存在、设置过期时间、获取剩余过期时间以及删除键。

javascript 复制代码
// 检查键是否存在
redis.exists('myKey').then((exists) => {
  console.log('Key exists:', exists);
});

// 设置键的过期时间
redis.expire('myKey', 10).then((didSetExpire) => {
  console.log('Key has an expiration time set:', didSetExpire);
});

// 获取键的剩余过期时间
redis.ttl('myKey').then((ttl) => {
  console.log('Time to live for key:', ttl);
});

// 删除键
redis.del('myKey').then((delCount) => {
  console.log('Deleted keys count:', delCount);
});

9. 事务处理

事务处理允许我们执行一系列操作,这些操作要么全部成功,要么全部失败。

javascript 复制代码
// 开始一个事务
redis.multi()
  .set('foo', 'bar')
  .get('foo')
  .exec().then((results) => {
    console.log('Transaction results:', results);
  });

10. 管道处理

管道处理允许我们批量执行多个命令,减少网络延迟。

javascript 复制代码
// 创建一个管道
redis.pipeline()
  .set('foo', 'bar')
  .get('foo')
  .exec().then((results) => {
    console.log('Pipeline results:', results);
  });

11. 脚本执行

脚本执行允许我们执行Lua脚本,这可以提高性能,尤其是在需要执行多个操作时。

javascript 复制代码
// 执行Lua脚本
redis.eval('return redis.call("set", KEYS[1], ARGV[1])', 1, 'myLuaKey', 'luaValue').then(() => {
  console.log('Lua script executed');
});

// 执行已加载的Lua脚本
const script = `
  local value = redis.call('get', KEYS[1])
  if value then
    return value
  else
    return 'nil'
  end
`;
redis.evalsha(script, 1, 'myLuaKey').then((result) => {
  console.log('Lua script result:', result);
});

以上是ioredis库中一些基本操作的入门指南。每个示例都包含了一个简单的操作和相应的代码,以帮助理解每个方法的作用。在实际开发中,你可能需要根据具体的业务逻辑来组合和扩展这些操作。希望这篇文章能帮助你更好地理解和使用ioredis

二. Promise风格与回调函数风格在Redis String类型CRUD操作中的对比

帮助理解:

ioredis库中,当你使用回调函数风格的API时,这些方法实际上返回的是 Promise对象 。这意味着即使你在方法调用的末尾提供了一个 回调函数ioredis内部仍然会返回一个 Promise对象,以便支持现代的异步处理方式。

当然,下面我将对比展示使用Promise风格的异步处理方式和使用回调函数风格的异步处理方式,以Redis的String类型为例

1. Promise风格(现代异步处理方式)

Promise风格是ES6引入的一种异步处理方式,它允许我们使用.then().catch()方法来处理异步操作的结果和错误。

  • 创建(Create)

    javascript 复制代码
    redis.set('key', 'value')
      .then(result => {
        console.log('Set result:', result); // 处理结果
      })
      .catch(err => {
        console.error('Error setting key:', err); // 处理错误
      });
  • 读取(Read)

    javascript 复制代码
    redis.get('key')
      .then(result => {
        console.log('Get result:', result); // 处理结果
      })
      .catch(err => {
        console.error('Error getting key:', err); // 处理错误
      });
  • 更新(Update)

    javascript 复制代码
    redis.set('key', 'new_value')
      .then(result => {
        console.log('Update result:', result); // 处理结果
      })
      .catch(err => {
        console.error('Error updating key:', err); // 处理错误
      });
  • 删除(Delete)

    javascript 复制代码
    redis.del('key')
      .then(result => {
        console.log('Delete result:', result); // 处理结果
      })
      .catch(err => {
        console.error('Error deleting key:', err); // 处理错误
      });

2. 回调函数风格(Node.js传统异步处理方式)

回调函数风格是在Promise之前Node.js中处理异步操作的主要方式。每个异步函数都接受一个回调函数作为最后一个参数,该回调函数在操作完成时被调用。

  • 创建(Create)

    javascript 复制代码
    redis.set('key', 'value', function(err, result) {
      if (err) {
        console.error('Error setting key:', err); // 处理错误
      } else {
        console.log('Set result:', result); // 处理结果
      }
    });
  • 读取(Read)

    javascript 复制代码
    redis.get('key', function(err, result) {
      if (err) {
        console.error('Error getting key:', err); // 处理错误
      } else {
        console.log('Get result:', result); // 处理结果
      }
    });
  • 更新(Update)

    javascript 复制代码
    redis.set('key', 'new_value', function(err, result) {
      if (err) {
        console.error('Error updating key:', err); // 处理错误
      } else {
        console.log('Update result:', result); // 处理结果
      }
    });
  • 删除(Delete)

    javascript 复制代码
    redis.del('key', function(err, result) {
      if (err) {
        console.error('Error deleting key:', err); // 处理错误
      } else {
        console.log('Delete result:', result); // 处理结果
      }
    });

3. 对比理解

  • 链式调用 vs 嵌套回调

    • Promise风格允许链式调用.then().catch(),使得代码更加线性和易于阅读,特别是在处理多个异步操作时,避免了所谓的"回调地狱"。
    • 回调函数风格需要嵌套回调,当有多个异步操作时,代码可能会变得难以阅读和维护。
  • 错误处理

    • Promise风格通过.catch()集中处理错误,使得错误处理更加集中和一致。
    • 回调函数风格在每个回调中单独处理错误,可能会导致错误处理代码的重复。
  • 异步控制

    • Promise风格提供了更多的控制力,如async/await语法,使得异步代码可以像同步代码一样编写,提高了代码的可读性和可维护性。
    • 回调函数风格在异步控制上较为有限,通常需要手动管理回调的执行顺序。

总的来说,Promise风格提供了一种更加现代和强大的异步处理方式,而回调函数风格则是Node.js中传统的处理方式。选择哪种方式取决于个人偏好和项目需求。

三. 使用Express和ioredis管理Redis中的代办任务:深入指南

这段代码是一个使用Express框架和ioredis库的Node.js应用程序,它提供了一个简单的API来管理代办任务。这些任务存储在Redis数据库中,使用哈希数据结构。下面我将结合这段代码,深入讲解Redis中的相关知识。

Redis哈希数据结构

Redis的哈希是一个字符串字段到字符串值的映射表,适合用于存储对象。在上面的代码中,每个代办任务都被表示为一个对象,并存储在Redis哈希中。

1. 代办任务的添加

javascript 复制代码
router.post('/add', (req, res) => {
    let { task } = req.body;
    let taskId = Date.now();
    const key = `task_obj:${taskId}`;
    redis.hset(key, { state: 0, code: 0, task: task }, (error, result) => {
        if (error) {
            console.log(error);
            return res.status(500).send('Error adding task');
        }
        res.send("Task added OK!");
    });
});
  • hset命令用于设置哈希表中的字段值。如果字段已存在,则会更新其值。
  • taskId是使用当前时间戳生成的唯一标识符,确保每个任务都有一个唯一的键。
  • key是任务的唯一键,格式为task_obj:<taskId>
  • 回调函数中的error参数用于处理可能发生的错误,result参数表示操作的结果。

2. 查看所有代办任务

javascript 复制代码
router.get('/tasks', async (req, res) => {
    const keys = await redis.keys("task_obj:*");
    let task_item;
    const task_arr = [];
    keys.forEach(async v => {
        task_item = await redis.hgetall(v);
        task_arr.push({ ...task_item, tid: v.substr(9) });
        if (keys.length == task_arr.length) {
            res.json({ code: 0, data: task_arr });
        }
    });
});
  • keys命令用于查找所有匹配给定模式的键。这里使用task_obj:*模式来查找所有任务对象。
  • hgetall命令用于获取哈希表中所有的字段和值。
  • 使用async/await语法来处理异步操作,使代码更易于阅读和维护。
  • task_arr数组用于存储所有任务对象,每个对象都包含一个额外的tid属性,它是任务的唯一标识符。

3. 获取单个代办任务

javascript 复制代码
router.get('/task', (req, res) => {
    let { id } = req.query;
    let key = `task_obj:${id}`;
    redis.hgetall(key, (error, task) => {
        if (error) {
            return res.status(500).send('Error retrieving task');
        }
        if (!task) {
            return res.status(404).send('Task not found');
        }
        res.json({ code: 0, task });
    });
});
  • 通过查询参数id来获取任务的键,并使用hgetall命令获取任务的详细信息。
  • 如果任务不存在,返回404状态码。

4. 更新代办任务

javascript 复制代码
router.post('/update', (req, res) => {
    let { id, task } = req.body;
    let key = `task_obj:${id}`;
    redis.hset(key, { code: 0, state: 0, task: task }, (error, result) => {
        if (error) {
            console.log(error);
            return res.status(500).send('Error updating task');
        }
        res.send('Task updated');
    });
});
  • 与添加任务类似,hset命令用于更新任务的状态和内容。
  • 如果更新失败,返回500状态码。

5. 删除代办任务

javascript 复制代码
router.get('/del', (req, res) => {
    let { id } = req.query;
    let key = `task_obj:${id}`;
    redis.del(key, (error, result) => {
        if (error) {
            console.log(error);
            return res.status(500).send('Error deleting task');
        }
        if (result === 0) {
            return res.status(404).send('Task not found');
        }
        res.send('Task deleted');
    });
});
  • del命令用于删除一个或多个键。
  • result参数表示被删除的键的数量。如果为0,则表示没有键被删除,可能是因为键不存在。

总结

这段代码展示了如何在Node.js应用程序中使用Redis来存储和管理代办任务。通过ioredis库,我们可以轻松地执行Redis命令,如hsethgetallkeysdel等,来操作哈希数据结构。此外,代码中使用了异步/等待(async/await)语法来简化异步操作的处理,使代码更加清晰和易于维护。

相关推荐
没事别瞎琢磨几秒前
十、统一 Runner 入口——能力检测与模式回退
人工智能·node.js
没事别瞎琢磨10 分钟前
八、环境隔离——构建安全的子进程环境
人工智能·node.js
Steadfast_GG14 分钟前
Redis中的通用命令
redis·缓存
小二·21 分钟前
Redis 内存溢出(OOM)排查与恢复实战
数据库·redis·bootstrap
pqk6V6Vep21 分钟前
Redis 分布式锁进阶第一篇讲解
数据库·redis·分布式
giaz14n9X38 分钟前
Redis 分布式锁进阶第六十一篇
数据库·redis·分布式
没事别瞎琢磨1 小时前
六、输出捕获与截断
人工智能·node.js
没事别瞎琢磨1 小时前
七、敏感路径预检——Protected Paths
人工智能·node.js
tyung1 小时前
Go 手写 Wait-Free SPSC 无界队列:无 CAS、无锁、泛型节点池
数据结构·后端·go
没事别瞎琢磨1 小时前
五、进程执行——spawn、超时与进程树清理
人工智能·node.js