2017-03-24 8 views
0

zurückzukehren Ich benutze JSZip, um ein Verzeichnis zu entpacken, die async läuft. Ich möchte eine Funktion schreiben, die eine Datei entpackt und gibt die Dateien mit ihm verbunden, wie folgt aus:Refactoring Versprechen, von Funktion

function unzipFile(filename){ 
    const zipper = new jsZip() 
    return fs.readFile(filename, function(err, data) { 
    return jsZip.loadAsync(data).then(function(zip) { 
     return zip.files 
    }) 
    }) 
} 

aber dies ist nur zurück undefined. Wie kann ich das async so machen, dass es das entpackte Verzeichnis in einer einzigen Funktion zurückgibt, und wenn ich eine Variable gleich ihrer Ausgabe setzen wollte, würde sie auf ihren Abschluss warten?

+1

weil in einem normalen Rückruf Rückkehr (die man auch nicht tun) hat no effect –

+0

du verwendest nicht einmal 'zipper' - also, die grundlagen sind sowieso falsch –

+0

Es ist nicht möglich. Lernen Sie sich mit Rückrufen vertraut zu machen. Sie können async/await-Schlüsselwörter als Syntax-Zucker verwenden, um es so aussehen zu lassen, als würden Sie Werte zurückgeben, aber auf einer bestimmten Ebene gibt eine asynchrone Funktion immer noch ein Versprechen zurück, so dass Sie irgendwann mit Rückrufen arbeiten müssen. Ich persönlich empfehle dringend, dass Leute async nicht verwenden/warten, bis sie Rückrufe und Versprechen verstehen. – slebetman

Antwort

4

Sie benötigen fs.readFile zuerst promisify - dann sollte nur eine regelmäßige Versprechen Kette

zum Beispiel den Trick

function unzipFile(filename){ 
    return new Promise((resolve, reject) => fs.readFile(filename, function(err, data) { 
     if(err) { 
      return reject(err); 
     } 
     resolve(data); 
    })) 
    .then(data => new jsZip().loadAsync(data)) 
    .then(zip => zip.files); 
} 
+1

Vielen Dank, das war sehr hilfreich! – Rob

+0

Wenn die ES2015 "arrow functions" Sie stolpern, können Sie den Code immer durch einen Transpiler wie babel laufen lassen: p –

+0

Nein, das ist ziemlich genau das, was mein Linter mir sagt – Rob

1

Sie müssen promisifyfs.readFile:

function readFileAsync(filename) { 
    return new Promise((resolve, reject) => { 
     fs.readFile(filename, function(err, data) { 
      if (err) reject(err); 
      else resolve(data); 
     }); 
    }); 
} 

Dann können Sie Kette auf, dass:

async function unzipFile(filename) { 
    const zipper = new jsZip(); 
    const data = await readFileAsync(filename); 
    const zip = await zipper.loadAsync(data); 
    return zip.files; 
} 
Verwandte Themen