我正在使用express创建一个web服务,它将从流中读取字符串数据,并使用该值响应HTTP POST请求。以下是定义S3Store.js
函数的readFileFromS3(.)
文件的代码:
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(.)
时返回空字符串,而不是直接从节点控制台调用相同的方法?
答案 0 :(得分:1)
您正在记录数据但是您没有将任何内容传递给完成回调(有关更多说明,请参阅下文):
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);
});
};
我冒昧地重写数据集以使用Buffer而不是字符串,但这显然不是必需的。
callback
参数是一个完成函数,意味着在读取S3流或者抛出错误时调用。错误处理已经到位,但不是在读取流中的所有数据时回调的部分,这就是我添加end
处理程序的原因。
此时,readStream
已用完(其中的所有内容都已读入allData
),并且当收集的数据作为第二个参数时,您调用完成回调
整个Node的常用习惯是完成回调(至少)有两个参数:第一个是错误,或者{0}没有错误,第二个是你想要的数据传递回调用者(在您的情况下,在您的路由处理程序中调用null
的匿名函数)。