首页 > 解决方案 > NodeJS处理发布的文件并返回文件

问题描述

所以,我一直在玩NodeJS,我想做的是接收客户端发送的文件,处理文件(不保存,需要逐行处理),然后将处理结果发送为文件下载。

所以我有以下路线:

app.post('/processFile', function(req, res) {
        var file = req.files.file;

        //Process file inline
        process.processFile(file, req).then((data) => {
            //res.setHeader('Content-Length', stat.size);
            res.setHeader('Content-Type', 'text/plain');
            res.setHeader('Content-Disposition', 'attachment; filename=tokenized.txt');
            res.write(data, 'binary');
            res.end();
        }).catch((err) => {
            res.send(err);
        });

    });

processFile 函数如下所示:

processFile: function(file) {
    return new Promise(function(resolve, reject) {
        var lineReader = require('readline').createInterface({
            input: fs.ReadStream(file)
        });

        var output = "";
        lineReader.on('line', function(line) {
            // Tokenize each line
            DoSomethingFunction(line).then((data) => {
                output += data + "\n";
            }).catch((err) => {
                reject(`Error in line [${line}].`);
            });
        });

        resolve(output);
    });    
}

当我测试它时,它什么也没做。我只是得到一个空响应,我做了一些测试,并注意到路由从 processFile() 承诺中得到了一个 reject(),但它没有任何消息。经过更多测试后,我注意到:

var lineReader = require('readline').createInterface({
   input: fs.ReadStream(file)
});

不起作用,它是发送“拒绝”的那个。

有什么想法有什么问题吗?

标签: javascriptnode.js

解决方案


问题是lineReader使用异步事件来收集其信息。

基本上,这意味着您在resolve(output)线路阅读器处理任何数据之前调用。相反,您需要监听另一个事件:“关闭”事件。这表示行阅读器已完成。

lineReader.on('close', () => {
  resolve(output);
});

不过有一个警告。您DoSomethingFunction似乎也是异步的。这意味着它有可能在“关闭”事件运行时等待做一些工作。处理此问题的一种方法是保存最新结果DoSomethingFunction并将其附加到“关闭”事件中。

// Initialize to a resolved promise just in case you don't receive
// any data from the user
let doSomethingPromise = Promise.resolve();

lineReader.on('line', (line) => {
  doSomethingPromise = DoSomethingFunction(line)
    .then((data) => {
      output += data + '\n';
    })
    .catch((err) => {
      reject(`Error in line [${line}].`);
    });
});

lineReader.on('close', () => {
  // Wait for the DoSomethingFunction to finish
  doSomethingPromise.then(() => resolve(output));
});

推荐阅读