流读取在nodejs中返回空
Stream read returning empty in nodejs
我正在使用 express 创建一个 Web 服务,它将从流中读取字符串数据,并使用该值响应 HTTP POST 请求。这是定义 readFileFromS3(.)
函数的 S3Store.js
文件的代码:
S3Store.js
S3Store.prototype.readFileFromS3 = function(filename, callback) {
var readConfig = {
'Bucket': 'shubham-test',
'Key': filename
};
var readStream = this.s3.getObject(readConfig).createReadStream();
var allData = '';
readStream.on('data', function(data) {
//data = Buffer.concat([allData, data]);
data = allData + data;
console.log("data: " + data);
});
readStream.on('error', function(err) {
callback(err, null);
});
现在,如果我从这样的终端调用此方法:
s3Instance.readFileFromS3('123.json', function(err, data) {
console.log(data);
});
我看到 data
的相应字符串已记录到控制台。但是,当我从 routes
中的一个内部为 HTTP POST
请求调用相同的方法时,服务响应 data
的值设置为空字符串。 POST 请求的代码:
router.post('/resolve', function(req, res) {
var commandJson = req.body;
var appId = commandJson['appId'];
var command = commandJson['text'];
if (appId == undefined || command == undefined) {
res.status(400).send("Malformed Request: appId: " + appId + ", command: " + command);
};
s3Store.readFileFromS3('123.json', function(err, data) {
res.send(data);
});
});
为什么从 HTTP POST 方法调用 readFileFromS3(.)
时 return 是一个空字符串,而不是当我直接从节点控制台 运行 调用相同的方法时?
您正在记录数据,但没有将任何内容传递给完成回调(更多解释请参见下文):
S3Store.prototype.readFileFromS3 = function(filename, callback) {
var readConfig = {
'Bucket': 'shubham-test',
'Key': filename
};
var readStream = this.s3.getObject(readConfig).createReadStream();
var allData = [];
// Keep collecting data.
readStream.on('data', function(data) {
allData.push(data);
});
// Done reading, concatenate and pass to completion callback.
readStream.on('end', function() {
callback(null, Buffer.concat(allData));
});
// Handle any stream errors.
readStream.on('error', function(err) {
callback(err, null);
});
};
我冒昧地重写了数据收集以使用缓冲区而不是字符串,但这显然不是必需的。
callback
参数是一个完成函数,意味着在完成读取 S3 流或引发错误时调用。错误处理已经到位,但不是在读取流中的所有数据时回调的部分,这就是我添加 end
处理程序的原因。
此时,readStream
已用尽(其中的所有内容都已读入 allData
),当收集到的数据 作为第二个参数时调用完成回调.
整个 Node 的常见习惯是完成回调接受(至少)两个参数:第一个是错误,或者 null
当没有错误时,第二个是你想要的数据传递回调用者(在您的情况下,是调用 res.send()
的路由处理程序中的匿名函数)。
我正在使用 express 创建一个 Web 服务,它将从流中读取字符串数据,并使用该值响应 HTTP POST 请求。这是定义 readFileFromS3(.)
函数的 S3Store.js
文件的代码:
S3Store.js
S3Store.prototype.readFileFromS3 = function(filename, callback) {
var readConfig = {
'Bucket': 'shubham-test',
'Key': filename
};
var readStream = this.s3.getObject(readConfig).createReadStream();
var allData = '';
readStream.on('data', function(data) {
//data = Buffer.concat([allData, data]);
data = allData + data;
console.log("data: " + data);
});
readStream.on('error', function(err) {
callback(err, null);
});
现在,如果我从这样的终端调用此方法:
s3Instance.readFileFromS3('123.json', function(err, data) {
console.log(data);
});
我看到 data
的相应字符串已记录到控制台。但是,当我从 routes
中的一个内部为 HTTP POST
请求调用相同的方法时,服务响应 data
的值设置为空字符串。 POST 请求的代码:
router.post('/resolve', function(req, res) {
var commandJson = req.body;
var appId = commandJson['appId'];
var command = commandJson['text'];
if (appId == undefined || command == undefined) {
res.status(400).send("Malformed Request: appId: " + appId + ", command: " + command);
};
s3Store.readFileFromS3('123.json', function(err, data) {
res.send(data);
});
});
为什么从 HTTP POST 方法调用 readFileFromS3(.)
时 return 是一个空字符串,而不是当我直接从节点控制台 运行 调用相同的方法时?
您正在记录数据,但没有将任何内容传递给完成回调(更多解释请参见下文):
S3Store.prototype.readFileFromS3 = function(filename, callback) {
var readConfig = {
'Bucket': 'shubham-test',
'Key': filename
};
var readStream = this.s3.getObject(readConfig).createReadStream();
var allData = [];
// Keep collecting data.
readStream.on('data', function(data) {
allData.push(data);
});
// Done reading, concatenate and pass to completion callback.
readStream.on('end', function() {
callback(null, Buffer.concat(allData));
});
// Handle any stream errors.
readStream.on('error', function(err) {
callback(err, null);
});
};
我冒昧地重写了数据收集以使用缓冲区而不是字符串,但这显然不是必需的。
callback
参数是一个完成函数,意味着在完成读取 S3 流或引发错误时调用。错误处理已经到位,但不是在读取流中的所有数据时回调的部分,这就是我添加 end
处理程序的原因。
此时,readStream
已用尽(其中的所有内容都已读入 allData
),当收集到的数据 作为第二个参数时调用完成回调.
整个 Node 的常见习惯是完成回调接受(至少)两个参数:第一个是错误,或者 null
当没有错误时,第二个是你想要的数据传递回调用者(在您的情况下,是调用 res.send()
的路由处理程序中的匿名函数)。