在浏览器中使用Javascript呈现文本流

在浏览器中使用Javascript呈现文本流,javascript,browser,stream,Javascript,Browser,Stream,使用nodejs服务器,我需要将下面显示的数据从文本文件流式传输到客户端浏览器。 文本文件中的每一行都是一个json对象,表示表中的一条记录 {"userId":443,"email":"bob@gmail.com","hashedPassword":"36583a77a098c02ef111e2f2521d77b58e420f2bc7e9bf930ec24b21d42ea2e0","timeStamp":1567439821109,"deleted":false} {"userId":447,

使用nodejs服务器,我需要将下面显示的数据从文本文件流式传输到客户端浏览器。
文本文件中的每一行都是一个json对象,表示表中的一条记录

{"userId":443,"email":"bob@gmail.com","hashedPassword":"36583a77a098c02ef111e2f2521d77b58e420f2bc7e9bf930ec24b21d42ea2e0","timeStamp":1567439821109,"deleted":false}
{"userId":447,"email":"alice@gmail.com","hashedPassword":"36583a77a098c02ef111e2f2521d77b58e420f2bc7e9bf930ec24b21d42ea2e0","timeStamp":1567439909013,"deleted":false}
{"userId":451,"email":"cliff@gmail.com","hashedPassword":"36583a77a098c02ef111e2f2521d77b58e420f2bc7e9bf930ec24b21d42ea2e0","timeStamp":1567443638340,"deleted":false}
...
本文末尾显示的nodejs函数成功地将文本文件流式传输到服务器上的新文件。
因此,源流是好的。
该函数还通过回调将sourceStream发送到浏览器

当我
console.log(responseTextStream)
在客户端浏览器中时,我会得到以下缓冲区。
[123、34、117、115、101、114、73、100、34、58、52、52、51、44、34、101、109、97、105、108、34、58、34、98、111、98、64、103、109、97、105、108、46、99、111、109、34、44、34、116、105,…]
所以我知道数据正在传送到客户端

我的问题是:我不知道如何在客户端处理流。
下面的伪代码显示了我试图在浏览器中使用javascript对流执行的操作。
有人能帮我找到正确的方向吗?
谢谢你,约翰

尝试:

var Astr=responseTextStream;
var line=“”;

对于(var i=0;iThank you@bob,我认为这解决了解析流的问题。我确信它会工作。但是我还不能测试它,因为我仍然不知道如何将流从nodejs传递到浏览器。我需要在另一篇文章中寻求有关此问题的帮助,因为出现了有关此问题的新信息。再次感谢您谢谢你的帮助。
// Populate the dbUsersList webpage with user records.
app.loadUsersListPage = function()
{  
  // Define which users will be retrieved from dbUsers.json
  // This is not being used for now so all records will be retrived.
  var QueryStringObject = {};

  // Ask the server for the JSON records found in the dbUsers file which match the QueryStringObject.
  // Then run the callback function defined here which inserts rows into the usersListTable on the webpage
  // and populates them with data from the file of JSON records returned.
  app.client.request(undefined,'api/aUsers','GET',QueryStringObject,undefined,function(statusCode,responseTextStream)
  {
    // if the call to handlers._users.get which is mapped to api/aUsers called back success.
    if(statusCode == 200) 
    {
      console.log(responseTextStream); // I can see the buffer is populated with data.  

      // Create a handle which can be used to manipulate the table on the webpage.
      var table = document.getElementById("usersListTable");

      // This next line causes an error because I am trying to use the  
      // split function on a stream but it demonstrates what I am 
      // trying to accomplish.  
      // I want to split the stream on each new line so that I can work 
      // with the json objects representing the records one at a time.  
      var recordsArray = responseTextStream.split('\n');

      recordsArray.forEach(function(jsonString)
      {
        var recordObject = JSON.parse(jsonString);

        if(recordObject)
        {
          // Insert a new row in the table.
          var tr = table.insertRow(-1);
          // Make the new row a member of the class 'checkRow'
          tr.classList.add('checkRow');

          // Insert five new cells into the new row.
          var td0 = tr.insertCell(0);
          var td1 = tr.insertCell(1);
          var td2 = tr.insertCell(2);   
          var td3 = tr.insertCell(3);          

          // load the new cells with data from the recordObject.
          td0.innerHTML = recordObject.userId;      
          td1.innerHTML = recordObject.email;
          td2.innerHTML = recordObject.timeStamp;      
          td3.innerHTML = '<a href="/users/edit?email=' + recordObject.userId + '">View / Edit / Delete</a>';
        }; // End of: if(recordObject)
      }); // End of: recordsArray.forEach(...)  
    } // End of: if the call to handlers._users.get which is mapped to api/aUsers called back successfully.
} // End of: app.loadUsersListPage = function(){...}
// End of: Populate the dbUsersList webpage with user records.
handlers._users.get = function(data, callback)
{
  // Create an empty map data structure which will be used to merge user records with the same email address.
  let usersMap = new Map();

  // This function sets up a stream where each chunk of data is a complete line in the dbUsers file.
  let readInterface = readline.createInterface
  (
    { // specify the file to be read.
      input: fs.createReadStream(_data.baseDir + '/dbPermissions/dbUsers' + '/' + 'dbUsers' + '.json'),
    }
  );

  // Now look at each record in the file and merge them into a map.
  readInterface.on('line', function(line) 
  {
    // Convert the JSON string (a single line from the dbUsers file) into lineValueObject.
    // These objects will written back to a new file after deleting some un-needed key/value pairs.
    let lineValueObject = JSON.parse(line);       

    // Declare a variable to serve as a key in the map to manage the lineValueObject.
    let userId = lineValueObject.userId;          

    if(lineValueObject.deleted === true)
    {
      // Remove this record from the map 
      usersMap.delete(userId);
    }
    else // this record has not been marked for deletion.
    {
      // Remove the hashed password key/value pair from the lineValueObject before returning it to the requester.
      delete lineValueObject.hashedPassword; 

      // Remove the deleted key/value pair from the lineValueObject before returning it to the requester.
      delete lineValueObject.deleted;            

      // Update this record in the map.
      usersMap.set(userId, lineValueObject);
    }

  }); // End of: readInterface.on('line', function(line){...}
  // End of: Look at each record...

  // This listener fires after we have looked through all the records in the dbUsers file.
  // The callback function defined here will stream the list of users back to the clients browser.
  readInterface.on('close', function() 
  {          
    // This readable stream will be used to write the result of the merge to a new file.
    const sourceStream = new Readable(); 

    for (const [key, valueObject] of usersMap)
    {
      // Convert the data object to a string.
      let stringData = JSON.stringify(valueObject);     

      // Load the readable stream with data.
      sourceStream.push(stringData + '\n');                  
    }       

    // Tell the stream no more data is coming.
    sourceStream.push(null);     

    // Create a writable stream and specify the file which will receive the data from the readable stream.
    let destinationStream = fs.createWriteStream(_data.baseDir + '/dbPermissions/dbUsers' + '/' + 'test' + '.txt', {flags : 'a'});

    // Populate the new text file from the sourceStream.
    // This is just to check that sourceStream is working as expected before sending the data to the client.
    // The pipeline will be removed when my problem has been solved.
    pipeline
    (
      sourceStream,
      destinationStream,
      function(error){if(error){console.log('There was an error.');}}
    );

    // Send the source stream to the client's browser
    callback(200, sourceStream);    

  }); // End of: readInterface.on('close', function(){...}
}; // End of: handlers._users.get = function(data, callback){do stuff}
var Astr = responseTextStream;
var line = "";
for(var i=0; i<Astr.length; i++){
    var chr = String.fromCharCode(Astr[i]);
    if(chr == "\n" || chr == "\r"){
        console.log("line: ",line);
        // do something with the line here
        // clear the line buffer to start the next line.
        line = "";
    } else {
        line += chr;
    }
}