2016-08-04 9 views
2

Ich bin neu in JavaScript. Ich habe ein Beispiel gefunden, um lokale Dateien mit Javascript unter StackOverflow zu öffnen. Nach einigem googlen kann ich meine Chrome setzen, um das Lesen von lokalen Dateien zu erlauben, und ich kann dann dieses Beispiel ausführen. Ich möchte jedoch die Zeichenfolge allText zurückgeben und später in meinem Skript verwenden. Aber die Zeichenfolge wird undefined außerhalb readTextFile().Öffnen Sie lokale Dateien in JavaScript

Es gibt eine ähnliche Frage here. Es scheint, dass es etwas mit der asynchronen Funktion von AJAX zu tun hat. Ich kann die Jargons im Moment kaum verstehen. Ich sehe nur nicht, warum in diesem Beitrag der dritte Parameter XMLHttpRequest.open() auf true gesetzt wird.

Wie auch immer, unten ist mein aktueller Code. Ich möchte allText außerhalb Funktion readTextFile() verwenden.

<!DOCTYPE html> 
<html> 
    <script> 
     function readTextFile(file) 
     { 
      var allText; 
      var rawFile = 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> 
+0

Mögliches Duplikat von [Wie gebe ich die Antwort von einem asynchronen Anruf zurück?] (Http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous- call) – Marty

+2

Sie deklarieren 'allText' zweimal (das macht zwei Variablen mit demselben Namen, aber unterschiedlichen Bereich), entfernen Sie das zweite' var' Schlüsselwort vor Ihrer Variablen. Viel Glück mit JavaScript! –

+0

@ SantiagoHernández Das ist Teil davon, aber es würde immer noch nicht die asynchrone Erfüllung Race-Bedingung zu lösen, und es wäre immer noch undefiniert, bis die XHR-Anfrage abgeschlossen ist. –

Antwort

3

Dies ist wahrscheinlich ein Problem Bereich. Da Sie allText asynchron festlegen, ist es nicht sofort verfügbar, nachdem die Funktion zurückgegeben wurde. Außerdem reinitialisieren Sie alleText innerhalb einer Funktion, was jedoch den Umfang der Rückgabe beeinträchtigt.

rawFile.onreadystatechange wird ausgeführt, nachdem die Funktion zurückgegeben wurde. Sie können entweder die Ausführung in den XHR-Rückruf verschieben oder die Funktion in ein Versprechen einfügen, was noch dazu führt, dass Sie Ihren Kontrollfluss ein wenig ändern müssen.

Bewegen Sie den 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); 
    }); 

Beide werden dafür sorgen, dass Ihr Skript nicht ALLTEXT zu verwenden, nicht versuchen, bis sie von der XHR zurückgegeben worden ist anfordern.

Obwohl wie Santiago Hernández hingewiesen, die XHR-Anfrage ist synchron, und das Problem mit dem Umfang war anderer Natur als ich zuerst angenommen. Das Problem liegt darin, die Variable innerhalb der Funktion neu zu deklarieren, was dazu führt, dass die zurückgegebene Variable nicht definiert ist.

+2

tatsächlich 'allText' wird syncronous gesetzt, blockiert den Haupt-Thread ... und es ist vollständig zugänglich, nachdem' rawFile.onreadystatechange' beendet –

+1

Yup! Mein Fehler. Ich habe das 'false'-Flag für Async auf der XHR-Anfrage anfangs nicht bemerkt. Kredit, wo Kredit fällig ist, hatten Sie die richtige Antwort :) –

+2

kein Problem :) .. BTW der Callback-Hölle ist wirklich eine Hölle –

Verwandte Themen