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