使用流处理时Knex.js的query-response事件未触发
Knex流处理模式下query-response事件失效的解决办法
knex的query-response事件在流处理模式下不会触发,核心原因是普通查询是等数据库返回完整结果集后才触发该事件,而流处理是直接把数据库的流式返回结果透传给你,knex内部不会去构建完整结果集,自然就不会触发绑定在完整结果节点上的query-response事件,官方文档确实没明确提这个细节。
如果要实现原来记录查询及响应耗时的需求,可以换用以下两种方式:
方式1:结合query事件和流的end事件统计耗时
通过query事件记录查询开始时间,在流结束时计算总耗时:
let queryStartTime; // 监听query事件,记录查询开始时刻 knexClient.on('query', () => { queryStartTime = Date.now(); }); const records = []; const readableStream = knexClient.raw('select * from columns').stream(); readableStream.on('data', (record) => { records.push(record); }); // 流结束时计算耗时 readableStream.on('end', () => { const elapsedTime = Date.now() - queryStartTime; console.log(`查询及响应总耗时:${elapsedTime}ms`); knexClient.destroy(); });
方式2:使用for await循环时统计耗时
如果习惯用for await语法,也可以在循环前后记录时间:
let queryStartTime; knexClient.on('query', () => { queryStartTime = Date.now(); }); const records = []; const readableStream = knexClient.raw('select * from columns').stream(); for await (const record of readableStream) { records.push(record); } // 循环结束即流处理完成,计算耗时 const elapsedTime = Date.now() - queryStartTime; console.log(`查询及响应总耗时:${elapsedTime}ms`); knexClient.destroy();
另外要注意:如果需要监听单条查询的事件,最好在每次查询前临时绑定事件,避免多个查询共用同一个时间变量导致统计错误。
内容的提问来源于stack exchange,提问作者Ballack
相关产品推荐
相关产品推荐

