简体   繁体   English

带有Express的Node.js:推送到一个空数组将返回一个空数组

[英]Node.js with Express: Push to an empty Array returns an empty Array

I am listing all files from all directories in /home/myComputer/Desktop/Research , and then filtering them with an if statement to only get the .txt files that I would like to read and store into arrays. 我列出了/home/myComputer/Desktop/Research所有目录中的所有文件,然后使用if语句过滤它们,以仅获取我想读取并存储到数组中的.txt文件。 All works fine, but pushing the data into the arrays is not functioning. 一切正常,但是将数据推入数组无法正常工作。 When I console log them, they return no value [] . 当我用控制台登录它们时,它们不返回任何值[]

I tried promise as well as call back function, but they didn't work for me because I didn't know how to implement them properly. 我尝试了promise和回调函数,但是它们对我没有用,因为我不知道如何正确实现它们。

app.get('/jsonData', function(req, res) {

    /* Define Arrays */
    var theFile = [];
    var theCategory = [];
    var theContent = [];

    var walk = function(dir, done) {
      var results = [];
      fs.readdir(dir, function(err, list) {
        if (err) return done(err);
        var i = 0;
        (function next() {
          var file = list[i++];
          if (!file) return done(null, results);
          file = dir + '/' + file;
          fs.stat(file, function(err, stat) {
            if (stat && stat.isDirectory()) {
              walk(file, function(err, res) {
                results = results.concat(res);
                next();
              });
            } else {
              results.push(file);
              next();
            }
          });
        })();
      });
    };


    //walk(process.env.HOME, function(err, results) {
    walk("/home/myComputer/Desktop/Research", function(err, results) {
      if (err) throw err;
      //console.log(results);

        results.map(function(val) {
            //Get the filename
            var fileName = val.match(/[^\/]+$/).join();
            //Get the category
            var category = val.substr(48).match(/[^\/]+/);

            if (fileName == 'written-speech.txt') {
                console.log('FOUND!: ' + fileName + ' Category: ' + category) //this works

                fs.readFile(val, 'utf8', function(err, contents) {
                    console.log(contents); // this works

                    theFile.push(fileName);
                    theCategory.push(category);
                    theContent.push(contents);
                });
            }
        })

    });

        console.log(theFile); // The problem: This returns an empty Array []
        console.log(theCategory); // The problem: This returns an empty Array []
        console.log(theContent); // The problem: This returns an empty Array []

});

I expect console.log(theFile); 我期望console.log(theFile); console.log(theCategory); and console.log(theContent); console.log(theContent); to return the data pushed in them. 返回推入其中的数据。

The reason for this is that many callbacks in Javascript are asynchronous, which means both fs.readdir and fs.readFile are asynchronous and their callbacks are not called immediately but slightly later (please read about Event Loop in javascript). 原因是Javascript中的许多回调都是异步的,这意味着fs.readdirfs.readFile都是异步的,它们的回调不会立即调用,而是稍后调用(请阅读javascript中的事件循环)。 So at the moment, when you log your arrays they are empty and data to them will be pushed later, eg in future. 因此,目前,当您记录阵列时,它们为空,稍后将向它们推送数据,例如在将来。 To avoid this you can either use synchronous methods (fs.readdirSync and fs.readFileSync) which is ugly and can cause performance issues if the app has a lot of other asynchronous operations. 为避免这种情况,您可以使用同步方法(fs.readdirSync和fs.readFileSync),该方法很丑陋,如果应用程序有很多其他异步操作,则可能导致性能问题。 If in your case it is just a simple script to read some data, it might be fine. 如果您的情况只是读取某些数据的简单脚本,那可能很好。 And the other, preferred way is to use promises or some library for managing callbacks, eg async . 另一种首选方法是使用Promise或某个库来管理回调,例如async Please read some articles regarding managing async code if these concepts are fully unfamiliar for you, eg https://dev.to/mrm8488/from-callbacks-to-fspromises-to-handle-the-file-system-in-nodejs-56p2 to get a basic understanding and see some use case examples. 如果您对这些概念完全不熟悉,请阅读一些有关管理异步代码的文章,例如https://dev.to/mrm8488/from-callbacks-to-fspromises-to-handle-the-file-system-in-nodejs-了解56p2的基本知识并查看一些用例示例。

Regarding your current version, there is no easy way to make it work without a lot of changes. 对于您当前的版本,没有很多更改就没有简单的方法来使其运行。 It is better to rewrite it to use the concepts I described earlier. 最好使用我之前描述的概念对其进行重写。

walk is an asynchronous function because fs.readdir is an asynchronous method and the console.log statements are running (in a synchronous manner) before the callback of fs.readdir getting invoked. walk是一个异步函数,因为fs.readdir是一个异步方法,并且在调用fs.readdir的回调之前,console.log语句正在运行(以同步方式)。

You can console the values of these variables at the end inside the callback of walk. 您可以在walk回调的结尾处控制台这些变量的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM