1

I am using JSZip to unzip a directory, which runs async. I want to write a function that unzips a file and returns the files associated with it, like this:

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

but this is just return undefined. How can I make this async so that it returns the unzipped directory in a single function, and if I wanted to set a variable equal to its output would await its completion?

Rob
  • 3,333
  • 5
  • 28
  • 71
  • 1
    because returning in a regular callback (which you don't do either) has no effect – Jaromanda X Mar 24 '17 at 02:50
  • you're not even using `zipper` - so, fundamentals are wrong anyway – Jaromanda X Mar 24 '17 at 02:53
  • It's not possible. Learn to get comfortable with callbacks. You can use async/await keywords as syntax sugar for promises to make it LOOK like you're returning values but at some level an async function still return a promise so at some point you need to deal with callbacks anyway. I personally **strongly** recommend that people don't use async/await until they understand callbacks and promises. – slebetman Mar 24 '17 at 02:56

2 Answers2

5

You'll need to promisify fs.readFile first - then just a regular Promise chain should do the trick

e.g.

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);
}
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
1

You will need to promisify fs.readFile:

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

Then you can chain onto that:

async function unzipFile(filename) {
    const zipper = new jsZip();
    const data = await readFileAsync(filename);
    const zip = await zipper.loadAsync(data);
    return zip.files;
}
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375