如何将node-zookeeper的connect事件处理逻辑Promise化以返回数据?
问题描述
我正在使用node-zookeeper连接ZooKeeper服务器。该库借助EventEmitter的on方法,允许在连接成功后操作ZooKeeper客户端。
示例代码如下:
this.client.on('connect', async () => { console.log('connected successfully'); // fetch data from zookeeper by supplying path const data = await client.get('/config', false); console.log(data); });
但上述代码无法返回获取到的配置数据,而该数据需要对外返回。我尝试使用bluebird进行Promise化,但未成功。请问如何将其Promise化,或采用其他可返回值的方法?
解决方案
1. 手动封装连接与数据获取逻辑为Promise
将客户端连接、数据获取的流程封装成Promise,就能对外返回数据:
function getZkConfig(client, path) { return new Promise((resolve, reject) => { // 用once替代on,避免重复绑定导致多次执行 client.once('connect', async () => { try { // 手动Promise化get方法(适配部分不支持Promise的旧版本库) const data = await new Promise((res, rej) => { client.get(path, false, (err, data) => { err ? rej(err) : res(data); }); }); resolve(data); } catch (err) { reject(err); } }); // 监听连接错误,防止Promise一直处于pending状态 client.once('error', reject); }); } // 使用示例 async function fetchConfig() { try { const configData = await getZkConfig(this.client, '/config'); return configData; // 此处可对外返回数据 } catch (err) { console.error('获取ZK配置失败:', err); throw err; } }
2. 正确使用Bluebird进行Promise化
如果坚持用Bluebird,需确保正确Promise化客户端方法:
const Promise = require('bluebird'); // Promise化客户端所有方法,生成带Async后缀的异步方法 Promise.promisifyAll(this.client); function getZkConfig(client, path) { return new Promise((resolve, reject) => { client.once('connect', async () => { try { // 调用Promise化后的getAsync方法 const data = await client.getAsync(path, false); resolve(data); } catch (err) { reject(err); } }); client.once('error', reject); }); }
关键注意点
- 必须用
once监听connect事件,避免重复触发逻辑 - 一定要绑定
error事件监听,防止连接失败时Promise挂起 - 部分旧版本
node-zookeeper原生不支持async/await,需手动处理回调转Promise
内容的提问来源于stack exchange,提问作者KnownUnknown
相关产品推荐
相关产品推荐

