Управление порядком загрузки при чтении строк файла - PullRequest
0 голосов
/ 02 ноября 2019

TLDR : Как открыть файлы (потоковый текст) (желательно асинхронный, поскольку файлы могут быть большими) и отобразить их по порядку?

У меня естьстраница, которая позволяет пользователям открывать несколько файлов. Каждая строка файла читается, а затем добавляется в массив с push в переменную display. Массив отображения затем отображается следующим образом:

document.getElementById('content').innerHTML = <table id ="mainView">' + display.join('') + '</table>';.

Это работает нормально, но поскольку файлы загружаются асинхронно, строки файла выталкиваются в массив не по порядку. Есть ли способ разработать механизм, который использует асинхронную загрузку файлов, но сохраняет порядок файлов? И, наконец, есть ли способ сделать это в javascript без библиотеки / фреймворка?

Порядок файлов определяется в соответствии с возрастающим соглашением о присвоении имен.

log12 <- lines in this log should appear first in the table
log16
log48
log103

Текущий вывод

log48 content
log12 content
log48 content
log103 content

Ожидаемый вывод

log12 content
log16 content
log48 content
log103 content

Вот суть того, как я загружаю несколько файлов, читаю их построчно, добавляю в массив иотобразить их на странице.

Форма загрузки файла вызывает эту функцию:

function handleFileSelect(evt) {
    var files = evt.target.files;
    fileArray = [].slice.call(files);
    for (var i = 0; i < fileArray.length; i++) { 
        console.log(fileArray[i].name);
        getContents(fileArray[i]);
    }
}

Загрузка и отображение строк для каждого файла. Следует отметить, что display - это глобальный массив.

function getContents(f){
    if(f){
        var reader = new FileReader();
        reader.readAsText(f, "UTF-8");
        var fileIndexname = f.name
    }

     reader.onload = function(evt){
        var lines = evt.target.result;
        // do some file splitting with regex here (removed for simplicity)
        for(var i = 0; i < lines.length; i++){
            display.push('<tr><td>' + lines[i] + '</td></tr>');
        }
        document.getElementById('content').innerHTML = '<table id ="mainView">' + display.join('') + '</table>';
    }
}

1 Ответ

2 голосов
/ 02 ноября 2019

Я бы полагался на Promise.all, чтобы поддерживать порядок загружаемых файлов.
При событии изменения входного файла я сопоставляю загруженные файлы с Promises, которые будут читать содержимое файла каждого файла.
Вывидно, что я использую другой API для чтения содержимого файла, так как Blob.text() является предпочтительным новым API на основе Promise.
Затем Promise.all () собирает результаты, сохраняя порядок загруженных файлов, если это то, что вам нужно.

Если вам нужно отсортировать все строки из всех файлов независимо от порядка загрузки, используйте эту функцию displayAllLinesSorted.

document.getElementById('upload').addEventListener('change', (event) => {
  const files = [].slice.call(event.target.files);
  const filePromises = files.map(file => {
    return file.text().then(result => {
    	return result.split(/[\r\n]+/g);
    });
  });
  Promise.all(filePromises).then(display);
});

function linesReducer(accumulator, currentValue) {
  return accumulator + `<tr><td>${currentValue}</td></tr>`;
}

function display(results) {
  const table = document.getElementById('table');
  table.innerHTML = results.flat().reduce(linesReducer, '');
}

function displayAllLinesSorted(results) {
  const table = document.getElementById('table');
  table.innerHTML = results.flat().sort().reduce(linesReducer, '');
}
<input type=file id=upload multiple />

<table id=table></table>

Просто примечание, потому что вы сказали:

асинхронно, поскольку файлы могут быть большими

Async не означает, что на больших файлах ваша производительность будет в порядке. Особенно в этом случае вы используете метод FileReader.readAsText(), который загружает все содержимое файла сразу.
Если вы действительно хотите обрабатывать большие файлы, вы должны использовать Blob.stream() или Blob.slice(), а ваш DOM <table> должен толькосодержать часть файла сразу. Ваш пользовательский интерфейс должен позволять пользователю перемещаться вперед и назад в файлах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...