尝试将zlib deflate包装成异步等待。

13

我正在尝试重构一些代码,以消除.then嵌套的问题,我需要一些帮助。

我正在尝试压缩一个JSON体,并将其传递到fetch调用中。 我已经成功地完成了这个过程,并在zlib回调函数中调用了fetch,但是代码变得混乱不堪。

因此,我一直在考虑将zlib调用包装在async await包装器中。 例如:

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);
    });
  });

}

compressBody函数返回一个Promise对象。reject和resolve的调用在zlib.deflate的回调函数中。

我实际上使用要压缩的JSON调用syncCompressBody函数。返回值是从compressBody的resolve调用得到的结果。

这两个函数都在一个辅助库中。在我的网页中,作为提交操作的一部分,我有...

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

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

然而,在compressBody函数中你可以看到“应该压缩”消息之前显示了“已压缩”的消息。我实际上希望代码在返回并恢复提交操作中的JS之前在syncCompressBody中等待。根据Bergi和Liam的评论,我修改了内容,并提供了一个例子,其中包含多个等待,每个函数都依赖于前一个函数...
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") ; 
}

首先显示pre-注释,然后是awaitStyle2开始,接着是theFirstAsyncFunctionX函数中的控制台日志信息,最后是post-消息。

我现在明白了为什么我的代码存在竞态条件,我走在正确的道路上吗?


1
“async function sync…”这个说法真的没有意义,不是吗? - Bergi
1
compressedBody = await syncCompressBody(jsonContent); - Liam
2
“我实际上调用了syncCompressBody,但返回的值是一个async function的promise。这是有道理的,因为你不能使zlib同步化,仍然需要等待它。” - Bergi
1
如果您不使用await,就无法获得结果。如果您无法使用await,则需要处理生成的Promise或不等待结果。 - Liam
你的代码没有(也从来没有)竞态条件,你试图同步调用异步代码。从我所看到的代码来看,你的修改似乎没问题。 - Liam
显示剩余3条评论
1个回答

36

我有一个与 gzip 相似的用例,如果这有帮助,请让我知道:

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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接