You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redis client.set正常但client.get失效问题(附Node.js代码)

问题排查:Redis缓存中间件client.get无法正常工作

问题代码

async function getRepos(req, res, next) {
    try {
        console.log('Fetching Data...');

        const { username } = req.params;

        const response = await fetch(`https://api.github.com/users/${username}`);

        const data = await response.json();

        const repos = data.public_repos;

        // Set data to Redis
        await client.setex(username, 3600, repos);

        res.send(setResponse(username, repos));
    } catch (err) {
        console.error(err);
        res.status(500);
    }
}

// Cache middleware
async function cache(req, res, next) {
    const { username } = req.params;
    console.log(username)
    await client.get(username, (err, data) => {
        if (err) throw err;

        if (data !== null) {
            res.send(setResponse(username, data));
        } else {
            next();
        }
    });
}

核心问题原因

  1. Async/Await与回调函数混用
    cache函数是async函数,但调用client.get时传入了回调。Redis客户端的get方法在传入回调时会以回调模式执行,此时await不会等待回调逻辑完成,函数会直接执行完毕,后续回调代码可能在请求响应发送后才触发,导致缓存逻辑完全失效。

  2. 未捕获的异步异常
    回调内的throw err会抛出未捕获的异步异常,async函数无法捕获回调内部的错误,这会导致进程崩溃或请求挂起,无法正常返回响应。

  3. Redis客户端Promise兼容性问题
    若使用的Redis客户端(如ioredis、node-redis v4+)支持Promise API,回调模式的使用会破坏异步流程的可控性,这是中间件逻辑异常的关键。

修复方案

将client.get改为Promise方式调用,用async/await正确等待缓存读取完成,并通过try/catch捕获错误:

async function cache(req, res, next) {
    const { username } = req.params;
    console.log(username);
    try {
        // 用Promise方式读取缓存,await等待结果
        const data = await client.get(username);
        
        if (data !== null) {
            // Redis存储的是字符串,需转为数字类型匹配存入时的格式
            const reposCount = parseInt(data, 10);
            res.send(setResponse(username, reposCount || data));
        } else {
            // 缓存不存在,进入下一个中间件
            next();
        }
    } catch (err) {
        console.error('缓存读取失败:', err);
        res.status(500).send('服务器缓存错误');
    }
}

额外注意点

  • Redis存储的所有值都是字符串类型,存入的public_repos是数字,取出时会变成字符串。如果setResponse期望数字类型,必须用parseInt或Number转换,避免返回数据类型不一致。
  • 确认Redis客户端版本支持Promise API(node-redis v4+默认支持,v3及以下需手动启用Promise模式)。

内容的提问来源于stack exchange,提问作者trek lucifer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 02:31:09