Primus是否支持异步插件?如何让注册的插件connection事件优先执行?
你遇到的执行顺序问题本质是Node.js原生EventEmitter的特性:EventEmitter触发事件时会按绑定顺序同步执行所有监听器,即便监听器是异步函数,也只会直接返回Promise,不会等待异步逻辑执行完成就会触发下一个监听器。你在插件里绑定的async connection监听器不会阻塞后续外部绑定的业务监听器执行,所以才会出现业务逻辑先运行、校验逻辑后运行的情况。
以下是两种可落地的解决方案:
方案1:使用Primus中间件实现前置校验(更推荐)
Primus的中间件系统天生支持异步逻辑,执行时机早于所有connection事件监听器,非常适合做参数校验、权限校验这类前置处理,插件修改如下:
public doPluginStuff = (primus, options) => { // 注册前置中间件,在connection事件触发前执行 primus.before('connection', async (req, res, next) => { try { await exectuteAsyncStuffHere(req); // 校验通过,进入后续流程 next(); } catch (err) { // 校验失败直接终止连接 res.writeHead(403); res.end('Validation failed'); } }); };
该方案不需要修改现有业务层的connection事件监听代码,校验逻辑会自动在所有业务逻辑执行前完成。
方案2:通过自定义事件控制执行顺序
如果你不想用中间件,也可以通过自定义事件隔离校验逻辑和业务逻辑,插件修改如下:
public doPluginStuff = (primus, options) => { primus.on('connection', async (spark) => { try { await exectuteAsyncStuffHere(); // 校验通过后触发自定义事件,业务逻辑监听该事件即可 primus.emit('validated-connection', spark); } catch (err) { spark.end('Validation failed'); } }); };
业务层代码调整为监听自定义事件即可:
this.primus.on('validated-connection', (spark) => { // 执行业务逻辑 });
两种方案都不需要你把插件逻辑硬编码到业务层的事件处理函数中。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

