简体   繁体   中英

Why is array length zero for a array that has contents?

Here's my code:

<script type="text/javascript" src="read.js"></script>
<script>
  var beats=[]
  beats=read('heartRate.txt')
  console.log(beats)           //label 1
  console.log(beats.length)    //label 2
  for (i = 0; i < beats.length; i++) { 
    console.log(beats[i])
    if(parseInt(beats[i])>80 || parseInt(beats[i])<50){
      document.getElementById('Alert').innerHTML('Abnormal heartrate of '+parseInt(beats[i]))
    }
  }
  console.log(beats)
</script>

And here is the contents of read.js:

function read(filename){
    var fs = require('fs');
      var readline = require('readline');
      var stream = require('stream');

      var str =[]
      var instream = fs.createReadStream(filename);
      var outstream = new stream;
      var rl = readline.createInterface(instream, outstream);

      rl.on('line', function(line) {
        //console.log(line+'\n')
        str.push(line)
      });

      rl.on('close', function() {
        // do something on finish here
        console.log(str.length)
      });
      return str;
}

Label 1: the value printed in the console shows the array with its contents.

Label 2: the length of the array is shown as 0. Is there any way to find the size of the array?

The console image is attached here:

控制台输出

I guess it is because of the read() function is asynchronous and it will take some time to finish the execution. Initially, the length was printed as zero then came the actual value 5. Try to return a promise from read() function and see how it works.

 function async read(filename){
    var fs = require('fs');
      var readline = require('readline');
      var stream = require('stream');

      var str =[]
      var instream = fs.createReadStream(filename);
      var outstream = new stream;
      var rl = readline.createInterface(instream, outstream);

      rl.on('line', function(line) {
        //console.log(line+'\n')
        str.push(line)
      });

      rl.on('close', function() {
        // do something on finish here
        console.log(str.length)
      });
      return str;
}

    <script type="text/javascript" src="read.js"></script>
    <script>
      var beats=[]
      read('heartRate.txt').then(function(data){
        beats=data
        //do your stuff here
      })

    </script>

Wont work beacuse,

console.log(beats)           //label 1
console.log(beats.length)  

Reading happens asynchronously, the push would execute only after,

rl.on('line', function(line) {
        //console.log(line+'\n')
        str.push(line)
      });

Add it on the close ( rl.on('close', ).

You should make read return a promise and only use the data when it's finished loading all data:

function read(filename){
  return new Promise((resolve, reject) => {
    const fs = require("fs");
    const readable = fs.createReadStream(filename);
    let data = [];
    readable.on('data', chunk => {
      data.push(chunk);
    });
    readable.on('end', () => {
      resolve(data);
    });
    readable.on('error', err => {
      reject(err);
    });
  }
}

You can use it like this:

<script type="text/javascript" src="read.js"></script>
<script>
  read('heartRate.txt').
  then(beats => {
    console.log(beats)           //label 1
    console.log(beats.length)    //label 2
    for (i = 0; i < beats.length; i++) { 
      console.log(beats[i])
      if(parseInt(beats[i])>80 || parseInt(beats[i])<50){
       document.getElementById('Alert').innerHTML(`Abnormal heartrate of ${parseInt(beats[i])} beats`);
      }
    }
    console.log(beats)
  })
  .catch(err => console.log(`Oh no, an error has occurred: ${err} `));

</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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