【问题标题】:Array doesnt have expected value - Nodejs数组没有预期值 - Nodejs
【发布时间】:2019-07-25 16:27:57
【问题描述】:

我正在运行一个脚本,它查看目录并列出文件,然后检查要处理的文件类型,如果扩展名匹配,则读取文件并读取文件的每一行(.col,它只是一个 txt 文件重命名)被插入到一个数组中。

现在读取文件并填充数组后,我想使用数组并进行一些进一步的处理,例如创建一个数据库记录。我在这里遗漏了一些非常基本的东西,因为在每个控制台日志中,我总是按如下方式获得所有文件内容的完整项目(在我的数组中)。

所以为了让它更简单一点: 数组为空。 然后文件被读取和处理,数组现在有 数组[0]=文件的第 0 行 array[0]=文件等的第 1 行

    const fs = require('fs');
const readline =require('readline');
var files = fs.readdirSync('/home/proj/data');
var path = require('path');
var model=[];
var lineReader=[];

for(var i=0; i<files.length; i++) {

    if(path.extname(files[i]) === ".col") {
       lineReader[i] = readline.createInterface({
            input: require('fs').createReadStream(files[i])
         });  

        lineReader[i].on('line', function (line) {  
          model.push(line); 
        }).on('close', async function() {
          console.log(model); 
      });

}

}

改为运行脚本,array[] 保存与扩展名匹配的所有文件的所有行。

非常感谢您的帮助,任何人都可以烧毁我的 JS,因为我很确定我在这里遗漏了一些基本的东西。

【问题讨论】:

  • 您需要使用 promise 或 asych/await,这里是现有答案的链接,可能对您有帮助 stackoverflow.com/questions/54034648/…
  • 你使用什么 Node.js 版本?您是否需要这种准备是非阻塞(异步)的,还是可以在服务器响应之前将其作为第一个程序阶段同步?
  • 我用的是Node.js V8.10.0,准备可以同步我没有问题。感谢您对我的问题感兴趣!
  • 您的文件大小是多少?将它们作为一个整体一个一个地读取并拆分成行数组是否可行?
  • 我添加了一个变体,用于同步处理不是很大的文件。让我知道这是否不合适)

标签: javascript node.js asynchronous


【解决方案1】:

如果你的文件不是很大并且同步方法没问题,你可以这样简化代码:

'use strict';

const fs = require('fs');
const path = require('path');

const model = [];

fs.readdirSync('/home/proj/data')
  .filter(name => path.extname(name) === '.col')
  .forEach((name) => {
    model.push(...fs.readFileSync(name, 'utf8').split('\n'));
  });

console.log(model);

【讨论】:

    【解决方案2】:

    那么,您想并行读取文件(因为您的程序就是这样做的)并将其放入数组数组中? 您可以使读取文件机制成为一个承诺,并使用Promise.all 使用它。这是一个帮助您入门的示例。

    const fs = require('fs');
    const readline = require('readline');
    var files = fs.readdirSync('./');
    var path = require('path');
    
    function readFile(fileName) {
        return new Promise(resolve => {
            const array = [];
            const lineReader = readline.createInterface({
                input: fs.createReadStream(files[i])
            });
            lineReader.on('line', function (line) {
                array.push(line);
            }).on('close', async function () {
                //do some proc
                console.log(array);
                resolve(array);
            });
        });
    }
    const readFilePromises = [];
    for (var i = 0; i < files.length; i++) {
        if (path.extname(files[i]) === ".js") {
            readFilePromises.push(readFile(files[i]));
        }
    }
    
    Promise.all(readFilePromises) //or await Promise.all([..])
        .then(data => {
            console.log(data);//will be array of arrays
        })
    

    如果您想要单个 Array,您可以随时使用 data.flat() 将结果展平

    【讨论】:

    • 感谢您的意见。实际上我不想并行读取文件。我想准备我的数组,然后以异步函数将其发送到数据库。这里的问题是我最初使用 1 个数组并在每次满足文件扩展名条件时重置它 (array=[];),所以在我看来,每次读取新的 .col 文件时我都会有一个干净的数组。我没有提到的另一个问题是,这是使用sailsjs 的Web 应用程序控制器的一部分。
    猜你喜欢
    • 2016-05-05
    • 2016-03-11
    • 1970-01-01
    • 2020-07-24
    • 2016-05-24
    • 1970-01-01
    • 2023-03-07
    • 2018-01-31
    • 1970-01-01
    相关资源
    最近更新 更多