Синхронное чтение локального файла с использованием Javascript

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

var nameslist = document.baseURI.split('.'); nameslist.pop(); nameslist = nameslist.join('.') + ".dat";
console.log("Attempting to read from file: " + nameslist);

var reader = new XMLHttpRequest() || new ActiveXObject('MSXML2.XMLHTTP');
reader.open("GET", nameslist, false);
reader.send(null);
nameslist = reader.responseText.split('\n');
nameslist.pop();

console.log("Elements read: " + nameslist.length);

Как и ожидалось, с файлом данных, состоящим из трех имен (для тестового примера), я получаю следующий результат в своем журнале консоли...

Попытка чтения из файла: file:///home/username/Desktop/test/test.dat test.js:11

Прочитано элементов: 3 test.js:19

Проблема в том, что я также получаю следующее предупреждение и ошибку в своем журнале, которые я хотел бы устранить (поскольку простое игнорирование этого может привести к проблемам в дальнейшем)...

Синхронный XMLHttpRequest в основном потоке устарел из-за его вредного воздействия на работу конечного пользователя. Для получения дополнительной помощи http://xhr.spec.whatwg.org/ test.js:14

синтаксическая ошибка test.dat:1

Из моего исследования предупреждения об обесценивании кажется, что Javascript как язык не любит синхронные операции, так как это замедляет скорость работы скрипта. Однако в этом случае мне нужно, чтобы все было загружено до того, как остальная часть скрипта сможет осмысленно работать. Я знаю, что могу реорганизовать это, чтобы поместить остальную часть скрипта в функцию, которая вызывается после того, как данные будут извлечены из responseText, и просто использовать true в строке reader.open, но есть ли лучший способ заставить JavaScript синхронно загрузить рассматриваемый файл данных без необходимости запуска функции main(), которая будет вызываться только один раз?

Что касается мошеннической ошибки, указывающей на первую строку файла данных, то я откровенно озадачен. Любые идеи о том, что может быть причиной такого поведения?

Заранее благодарю за любые ответы, которые я получу от сообщества.


person Aaron Nichols    schedule 04.03.2015    source источник
comment
Нет, нет способа использовать SJAX без этого предупреждения и невозможно использовать AJAX без обратного вызова. Обратите внимание, что это не замедляет ваш скрипт, а просто делает браузер непригодным для использования во время загрузки (что может не быть реальной проблемой при запуске, за исключением случаев, когда загрузка не удалась).   -  person Bergi    schedule 05.03.2015
comment
Моя ставка на эту синтаксическую ошибку заключается в том, что он пытается интерпретировать файл .dat как xml. Попробуйте установить свойство responseType.   -  person Bergi    schedule 05.03.2015
comment
@ Берги: свойство responseType не может быть изменено, поэтому я думаю, что нет способа обойти эту ошибку как асинхронную. С вашей собственной связанной страницы: Примечание. Начиная с Gecko 11.0 (Firefox 11.0 / Thunderbird 11.0 / SeaMonkey 2.8), а также со сборкой WebKit 528, эти браузеры больше не позволяют использовать атрибут responseType при выполнении синхронных запросов. Попытка сделать это вызывает исключение NS_ERROR_DOM_INVALID_ACCESS_ERR. Это изменение было предложено W3C для стандартизации.   -  person Aaron Nichols    schedule 05.03.2015


Ответы (1)


Решается переписыванием кода следующим образом:

var nameslist = document.baseURI.split('.'); nameslist.pop(); nameslist = nameslist.join('.') + ".dat";
console.log("Attempting to read from file: " + nameslist);

var reader = new XMLHttpRequest() || new ActiveXObject('MSXML2.XMLHTTP');
reader.open("GET", nameslist);
reader.onloadend = main;
reader.responseType = "text";
reader.send();

function main()
{
 nameslist = reader.responseText.split('\n'); nameslist = nameslist.filter(function(n){return n;}).sort();
 console.log("Elements read: " + nameslist.length);
 // Additional code to be run after the load is complete goes in this block, starting at this line.
}
person Aaron Nichols    schedule 04.03.2015
comment
@Bergi: Спасибо за вашу помощь в этом. Мне не нравится, что он должен быть асинхронным, чтобы работать без ошибок и предупреждений, но я полагаю, что он должен быть таким, чтобы браузеры, работающие с этим кодом, были счастливы. - person Aaron Nichols; 05.03.2015