使用Express与whatsapp-web-js构建API遇响应延迟及请求阻塞问题
问题分析与修复方案
你的代码核心问题有两个:
- 重复绑定事件监听器:每次访问
/路由时,都会给client的ready事件新增一个回调函数。首次请求时,客户端还没就绪,等ready触发后返回响应;但后续请求时,ready事件早已触发过,新绑定的回调永远不会执行,导致请求一直挂起阻塞。 - 事件触发时机错误:
ready事件只在WhatsApp客户端初始化完成、登录成功时触发一次,不是每次请求都会触发,所以不能把响应逻辑放在这个事件的回调里处理请求。
修复后的代码实现
var express = require("express"); var app = express(); const qrcode = require('qrcode-terminal'); const { Client, LocalAuth } = require('whatsapp-web.js'); const client = new Client({ authStrategy: new LocalAuth() }); // 标记客户端是否就绪 let isClientReady = false; // 在路由外初始化客户端,只绑定一次ready事件 client.on('ready', () => { console.log('WhatsApp客户端已就绪'); isClientReady = true; }); client.on('qr', (qr) => { qrcode.generate(qr, { small: true }); console.log('扫描上方二维码登录WhatsApp'); }); client.initialize(); app.get("/", (req, res) => { if (!isClientReady) { return res.status(503).json({ error: 'WhatsApp客户端未就绪,请先扫描二维码登录' }); } // 这里实现获取群聊ID的逻辑 client.getChats().then(chats => { const groupChats = chats.filter(chat => chat.isGroup); const groupIds = groupChats.map(chat => ({ id: chat.id._serialized, name: chat.name })); res.json(groupIds); }).catch(err => { res.status(500).json({ error: '获取群聊列表失败', details: err.message }); }); }); app.listen(3000, () => { console.log("Server running on port 3000"); });
关键修改点说明
- 提前初始化客户端:在路由定义前就初始化
client并绑定ready、qr事件,确保事件只绑定一次。 - 就绪状态标记:用
isClientReady变量跟踪客户端状态,路由里直接判断状态,避免依赖事件回调处理请求。 - 正确的请求处理逻辑:客户端就绪后,直接在路由里调用
getChats()获取群聊列表,过滤出群聊并提取ID,无需等待事件触发。 - 错误处理:添加了客户端未就绪时的提示,以及获取群聊失败时的错误返回,避免请求无响应。
内容的提问来源于stack exchange,提问作者user18039014
相关产品推荐
相关产品推荐

