Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to wrap zlib deflate into async await

I'm trying to refactor some code to remove .then pyramid and I need some help.

I'm trying to zip a JSON body to pass into a fetch call. I've actually managed this already, and called the fetch withing the zlib callback, but the code is becoming messy.

So, I've been looking at wrapping the zlib call in an async await wrapper. E.g.

async function syncCompressBody(body) {

  //return await compressBody(body);
  const compressedData = await compressBody(body);
  console.log("compressedData");
  console.log(compressedData);
  return compressedData;

}

function compressBody(body) {

  return new Promise( function( resolve, reject ) {

    zlib.deflate(body, (err, buffer) => {
      if(err){
        console.log("Error Zipping");
        reject(err);
      }
      console.log("Zipped");

      resolve(buffer);
    });
  });

}

The compressBody function returns a promise. The reject and resolve calls are in the callback of zlib.deflate.

I actually call syncCompressBody with the JSON to compress. The returned value is the result of the resolve call from compressBody.

The two functions are in a helper library. In my webpage, as part of the submit action, I have...

  console.log(jsonContent);
  const compressedBody = syncCompressBody(jsonContent);
  console.log(compressedBody);

  console.log("should be zipped by now..." + compressedBody);

However, the 'should be zipped' message is displayed before the 'zipped' message you can see in the compressBody function. What I actually want is for the code wait in syncCompressBody before returning to and resuming the JS in the submit action.

Edits following feedback....

Based on Bergi's and Liam's comments, I came up with this example of several awaits with each function relying on the previous function....

function awaitStyle2x(){
    console.log("pre-awaitStyle2 start");  
    (async () => {
      console.log("awaitStyle2 start")        
      const t = await theFirstAsyncFunctionX("pass it on");
      const u = await theNextAsyncFunctionX(t);
      const v = await aThirdAsyncFunctionX(u);
        console.log("awaitStyle2 finshed - " + v)
    })().catch(e => { /* handle the error */});   
    console.log("post-awaitStyle2 finished") ; 
}

The pre- comment is displayed first, then awaitStyle2 start, then the console log message in function theFirstAsyncFunctionX, then the post- message.

I can see now why my code has the race condition, am I on the right track?

like image 822
Chris Adams Avatar asked Feb 28 '18 10:02

Chris Adams


Video Answer


1 Answers

I had a similar use case with gzip, let me know if this helps:

const util = require('util');
const zlib = require('zlib');
const deflate = util.promisify(zlib.deflate);

console.log(jsonContent);
const compressedBody = await deflate(jsonContent);
console.log(compressedBody);

console.log("should be zipped by now..." + compressedBody);
like image 79
Andrew Avatar answered Nov 05 '22 20:11

Andrew