Node.js使用Redis客户端报queueMicrotask未定义错误如何解决
问题根因
- 你使用的是v4及以上版本的Redis Node客户端,该版本依赖
queueMicrotask内置API,这个API仅在Node.js v11.0.0及以上版本提供,你当前运行环境的Node.js版本低于要求,所以触发未定义错误 - 现有代码存在逻辑缺陷:Redis客户端初始化是异步操作,服务启动时可能还未完成连接就收到请求,调用Redis操作时会出现客户端未就绪的异常
解决方案
方案1:升级Node.js(推荐)
将你的Node.js环境升级到v12.x及以上的LTS版本,即可兼容最新版Redis客户端的所有依赖。同时补全代码中的逻辑漏洞,修改后的完整代码如下:
const express = require("express"); const axios = require("axios"); const cors = require("cors"); const Redis = require("redis"); const DEFAULT_EXPIRATION = 3600 const app = express(); app.use(express.urlencoded({ extended: true})); app.use(cors()); let redisClient; (async () => { try { redisClient = Redis.createClient(); redisClient.on('error', (err) => console.log('Redis Client Error', err)); await redisClient.connect(); // 确保Redis连接成功后再启动服务 app.listen(3000, () => { console.log("服务已启动,监听端口3000"); }); } catch (e) { console.error("Redis连接失败:", e); process.exit(1); } })(); app.get("/photos", async(req,res) => { try { const albumId = req.query.albumId; const cacheKey = `photos?albumId=${albumId}`; // 先查缓存 const cacheData = await redisClient.get(cacheKey); if (cacheData) { console.log("cache hit"); return res.json(JSON.parse(cacheData)); } // 缓存 miss 拉取第三方数据 console.log("cache miss"); const { data } = await axios.get( "https://jsonplaceholder.typicode.com/photos", { params : { albumId } } ); // 写入缓存 await redisClient.SETEX(cacheKey, DEFAULT_EXPIRATION, JSON.stringify(data)); return res.json(data); } catch (e) { console.error("接口处理失败:", e); res.status(500).json({error: "服务内部错误"}); } }) app.get("/photos/:id", async(req,res) => { try { const { data } = await axios.get( `https://jsonplaceholder.typicode.com/photos/${req.params.id}` ); res.json(data); } catch (e) { console.error("查询照片详情失败:", e); res.status(500).json({error: "服务内部错误"}); } })
方案2:降级Redis客户端版本
如果暂时无法升级Node.js版本,可以卸载现有高版本Redis包,安装v3版本的Redis客户端,v3版本不需要依赖queueMicrotaskAPI,适配低版本Node.js:
- 执行命令降级包:
npm uninstall redis && npm install redis@3
- 替换为v3版本适配的代码,v3版本不需要手动调用
connect()方法:
const express = require("express"); const axios = require("axios"); const cors = require("cors"); const Redis = require("redis"); const DEFAULT_EXPIRATION = 3600 const app = express(); app.use(express.urlencoded({ extended: true})); app.use(cors()); // v3版本直接初始化客户端即可,不需要异步connect const redisClient = Redis.createClient(); redisClient.on('error', (err) => console.log('Redis Client Error', err)); app.get("/photos",async(req,res) => { const albumId = req.query.albumId; const cacheKey = `photos?albumId=${albumId}`; redisClient.get(cacheKey, async (error, photos) => { if(error) { console.error(error); return res.status(500).json({error: "缓存查询失败"}); } if(photos != null){ console.log("cache hit"); return res.json(JSON.parse(photos)) } console.log("cache miss"); const { data } = await axios.get( "https://jsonplaceholder.typicode.com/photos", { params : { albumId } } ) redisClient.SETEX(cacheKey, DEFAULT_EXPIRATION, JSON.stringify(data)); return res.json(data); }) }) app.get("/photos/:id",async(req,res) => { const { data } = await axios.get( `https://jsonplaceholder.typicode.com/photos/${req.params.id}` ) res.json(data); }) app.listen(3000, () => { console.log("服务已启动,监听端口3000"); });
内容的提问来源于stack exchange,提问作者user17513056
相关产品推荐
相关产品推荐

