[mysql] query.stream 将查询结果流写入response如何handle中途可能产生的error?
有时会碰到向db查询大量记录,需要边接收边处理的场景。mysql模块提供了一个流式查询的方法streaming query rows。 如果需要每收到一条记录就写入到http response中,如何处理接收过程中可能产生的错误呢?此时response head已经发出200,且已经正常发送了部分数据,当query发生错误时,如何通知客户端发生了错误? 代码如下:
const pool = require('mysql').createPool(...);
const http = require('http');
http.createServer((req, res)=> {
response.statusCode = 200;
let sql = 'SELECT * FROM tb1';
let query = pool.query(sql);
query
.on('result', (row)=> {
res.write(JSON.stringify(row));
})
.on('error', (err)=> {
res.end(); // 如何handle中途可能产生的error?
})
.on('end', ()=> {
res.end();
});
}).listen(8000);
4 回复
这里是不是你理解有一点偏差 write只会向缓冲区写数据,此时并不会发送给客户端,只有当你调用res.end()方法时,才会把缓冲区的数据发送给客户端,所以这里你完全可以写成类似这样的:
const pool = require('mysql').createPool(...);
const http = require('http');
http.createServer((req, res)=> {
let sql = 'SELECT * FROM tb1';
let query = pool.query(sql);
let dataArr = [];
query
.on('result', (row)=> {
dataArr = dataArr.concat(row);
})
.on('error', (err)=> {
err = err instanceof Error && err || new Error(err);
res.statusCode = 500;
res.end(err.message);
})
.on('end', ()=> {
res.statusCode = 200;
res.end(JSON.stringify(dataArr));
});
}).listen(8000);
http协议一个请求只能对应一次响应,这是由协议本身决定的,如果你想多次发送数据给客户端,可以用websocket或者索性是TCP协议
既然使用的stream,那你就不需要等数据完全接收完了再发送,直接
query.pipe(res);
end
事件时,
.on('end', ()=> {
res.end();
});
不然数据量大了之后,说不定就会 boom
!
@hyj1991 原来如此,谢谢解答!
@luoyjx 谢谢解答,我就是为了解决查询数据量大时的发送问题,现已改用了pipe