Откройте локальные файлы в JavaScript

Я новичок в JavaScript. Я нашел пример, чтобы открыть локальные файлы с JavaScript наПереполнение стека, После некоторого поиска в Google, я могу установить мойХром чтобы разрешить чтение локальных файлов, и я могу запустить этот пример. Тем не менее, я хочу вернуть строкуallText и использовать его позже в моем сценарии. Но строка становитсяundefined внеreadTextFile().

Есть похожий вопросВот, Кажется, что это как-то связано с асинхронной функциейAJAX, Я едва могу понять жаргон в данный момент. Я просто не понимаю, почему в этом посте третий параметрXMLHttpRequest.open() установлено бытьtrue.

Во всяком случае, ниже мой текущий код. Я хочу использоватьallText внешняя функцияreadTextFile().

<!DOCTYPE html>
<html>
    <script>
        function readTextFile(file)
        {   
            var allText;
            var rawFil,e = new XMLHttpRequest();
            rawFile.open("GET", file, false);
            rawFile.onreadystatechange = function ()
            {
                if(rawFile.readyState === 4)
                {
                    if(rawFile.status === 200 || rawFile.status == 0)
                    {
                        var allText = rawFile.responseText;
                        alert(allText);
                    }
                }
            }
            rawFile.send(null);
            return allText; // this is the part that goes wrong I think
        }

        t = readTextFile("foo.file");
        document.write(t) // print out "undeifned" instead of the correct answer

    </script>
</html>
 Chris04 авг. 2016 г., 03:19
@BrandonAnzaldi, хотя я не совсем понимаю вашу озабоченность, этот скрипт работает сейчас
 Brandon Anzaldi04 авг. 2016 г., 04:21
Должно быть правильно сейчас @Chris. :) Надеюсь, я смог помочь.
 Chris04 авг. 2016 г., 03:54
хорошо, спасибо. Я отмечу ответ @BrandonAnzaldi принятым после того, как он исправит его
 Chris04 авг. 2016 г., 03:48
@ SantiagoHernández Я также видел комментарии об использовании синхронизации. AJAX устарела. Просто любопытно, что такое «правильное» решение?
 Brandon Anzaldi04 авг. 2016 г., 03:16
@ SantiagoHernández Это часть этого, но он все равно не решит условие гонки асинхронного выполнения, и все равно будет неопределенным, пока запрос XHR не будет завершен.
 Brandon Anzaldi04 авг. 2016 г., 03:51
@Cris Это должно быть все, что вам нужно сделать. Или вы можете полностью удалить третий аргумент, так как он по умолчаниюtrue.
 Chris04 авг. 2016 г., 03:50
@ SantiagoHernández Полагаю, что после замены «ложь» на «правда»?
 Santiago Hernández04 авг. 2016 г., 03:49
Лучшее решение - сделать это в духе Брэндона Анзальди.
 Brandon Anzaldi04 авг. 2016 г., 03:26
@ SantiagoHernández Аааа, я даже не заметил, что XHR изначально был синхронным. Я предполагал, что проблема возникла из-за обратного вызова, который не совпадает с остальной частью сценария. Переопределение переменной было правильным ответом для решения насущной проблемы! И асинхронный поток управления JS может быть болью, чтобы обернуть вашу голову независимо от уровня навыка. Это очень легко попасть вад обратного вызова, :)
 Brandon Anzaldi04 авг. 2016 г., 03:21
Рад слышать, что это сработало! Тем не менее, для нелокальных файлов, или если есть задержка при чтении локальных файлов, функция вернетallText прежде чем он был определенonreadystatechanged, Поскольку он локальный, он может происходить более или менее мгновенно и не вызывать проблем. :) РЕДАКТИРОВАТЬ: не заметил, что запрос XHR был в синхронном режиме. :П
 Chris04 авг. 2016 г., 03:18
Черт ... Я потратил 2 часа на эту вещь. Спасибо @ СантьягоХернандес
 Santiago Hernández04 авг. 2016 г., 03:22
Крис не проблема !, @BrandonAnzaldi да, я знаю, что делать синхронизацию Ajax-запросов - плохая практика, но он изучает основы, которые я предполагаю
 Santiago Hernández04 авг. 2016 г., 03:13
ты заявляешьallText дважды (что делает две переменные с одинаковым именем, но разной областью действия), удалите вторуюvar Ключевое слово перед вашей переменной. Удачи с JavaScript!
 Marty04 авг. 2016 г., 03:12

Ответы на вопрос(1)

Решение Вопроса

На самом деле это, скорее всего, проблема сфер. Поскольку вы устанавливаете allText асинхронно, он не доступен сразу после возврата из функции. Кроме того, вы переинициализируете allText внутри функции, которая независимо от области действия возвращается.

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

Переместитьdocument.write:

<!DOCTYPE html>
<html>
    <script>
        function readTextFile(file)
        {   
            var allText;
            var rawFile = new XMLHttpRequest();
            rawFile.open("GET", file);
            rawFile.onreadystatechange = function ()
            {
                if(rawFile.readyState === 4)
                {
                    if(rawFile.status === 200 || rawFile.status == 0)
                    {
                        allText = rawFile.responseText;
                        document.write(allText);
                    }
                }
            }
            rawFile.send(null);
        }

        readTextFile("foo.file");

    </script>
</html>

Promisified:

function readTextFile( file ) {
  return new Promise( function ( fulfill, reject ) {

    var allText;
    var rawFile = new XMLHttpRequest();
    rawFile.open( "GET", file );
    rawFile.onreadystatechange = function () {
      if ( rawFile.readyState === 4 ) {
        if ( rawFile.status === 200 || rawFile.status == 0 ) {
          fulfill( rawFile.responseText )
        }
      }
    }
    rawFile.send( null );
  } );
}
readTextFile( "foo.file" )
  .then( function ( t ) {
    document.write( t );
  } );

И то, и другое гарантирует, что ваш скрипт не будет пытаться использовать allText, пока он не будет возвращен XHR-запросом.

Хотя какСантьяго Эрнандес указал, что запрос XHR является синхронным, и проблема с областью действия была иной природы, чем я сначала предполагал. Проблема заключается в том, чтобы переопределить переменную внутри функции, в результате чего возвращаемая переменная будет неопределенной.

 Brandon Anzaldi04 авг. 2016 г., 03:28
Ага! Виноват. Я не заметилfalse Первоначально флаг для асинхронного запроса XHR. Кредит, где кредит должен, у вас был правильный ответ :)
 Chris04 авг. 2016 г., 03:39
@BrandonAnzaldi Я использую блокнот ++. офигенно попробую. Спасибо!
 Santiago Hernández04 авг. 2016 г., 03:31
нет проблем :) .. кстати, обратный вызов ад действительно ад
 Brandon Anzaldi04 авг. 2016 г., 03:35
@Chris Это не глупый вопрос вообще! Я даже не заметил основной проблемы изначально. Линтер должен помочь вам избежать этих проблем. Независимо от того, какой редактор вы используете, вероятно, для него есть плагин для линтеров :) ES-Lint или JSHint - это два пришедших на ум линтера, которые дадут вам стилистические и синтаксические подсказки, а также помогут выявить проблемы, которые вы могли бы пропустить. :)
 Brandon Anzaldi04 авг. 2016 г., 03:40
@Крисstackoverflow.com/questions/1046810/using-jslint-in-notepad Не волнуйтесь. Удачного кодирования!
 Santiago Hernández04 авг. 2016 г., 03:26
на самом делеallText устанавливается синхронно, блокируя основной поток ... и он становится полностью доступным послеrawFile.onreadystatechange отделки
 Chris04 авг. 2016 г., 03:33
@ оба из вас, извините за этот тупой вопрос, который я только что опубликовал. Как упоминал Сантьяго, это действительно просто проблема синтаксиса. Я был поражен всем жаргоном во время отладки. Кроме того, есть ли JavaScript IDE, чтобы помочь мне избежать такого рода ошибок?

Ваш ответ на вопрос