Search code examples
javascripthtmlnode.jsnode-webkit

How to update in html page during nodejs readline process


I want to dynamically change the content of a

element in my html page during nodejs readline process.

Here is a jsfiddle example to shown the display effect I want to fulfill: https://jsfiddle.net/09kuyn7v/

But I want to dynamically display lines from my local file, but not from an array defined within the function as in the jsfiddle example.

I have used readline module in my read-file-version clickTest() function:

function clickTest(){
  var fs = require('fs');
  var lineReader = require('readline').createInterface({
    input: fs.createReadStream(filePath)
  });

  lineReader.on('line', function(line){
    document.getElementById("demo").innerHTML += line;
  });
}

But when I click the button, the page was just like being freezed and then the lines were displayed simultaneously (not one by one as shown in the jsfiddle example above).


Solution

  • First of all, every time you call that function you do require('readline') and require('fs') so I would move that up the script.

    I would suggest two approaches:

    Pausing read

    var readline = require('readline');
    var fs = require('fs');
    
    function clickTest(){
      var lineReader = readline.createInterface({
        input: fs.createReadStream(filePath)
      });
    
      lineReader.on('line', function(line){
        // pause emitting of lines...
        lineReader.pause();
    
        // write line to dom
        document.getElementById("demo").innerHTML += line;
    
        // Resume after some time
        setTimeout(function(){
          lineReader.resume();
        }, 1000);
      });
    
      lineReader.on('end', function(){
        lineReader.close();
      });
    }
    

    This approach should read one line, then pause and resume after some time you specify.

    Buffering lines

    var readline = require('readline');
    var fs = require('fs');
    var lines = [];
    
    function clickTest(){
      var lineReader = readline.createInterface({
        input: fs.createReadStream(filePath)
      });
    
      lineReader.on('line', function(line){
        lines.push(line)
      });
    
      lineReader.on('end', function(){
        lineReader.close();
    
        printLine(0);
      });
    }
    
    function printLine(index){
      // write line to dom
      document.getElementById("demo").innerHTML += lines[index];
    
      if (index < lines.length - 1){
          setTimeout(function(){
            printLine(index + 1); 
          }, 1000);
      }
    }
    

    This approach will save all the lines into an array and then slowly prints them out.

    Please note that I haven't got node-webkit to actually test it, so you might find a bug in the code, but it should give you general idea