在nodejs

时间:2015-06-17 08:44:58

标签: node.js express node-webkit

我正在使用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(.)时返回空字符串,而不是直接从节点控制台调用相同的方法?

1 个答案:

答案 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的匿名函数)。